diff --git a/asset/protos/asset_service.proto b/asset/google/cloud/asset_v1beta1/proto/asset_service.proto
similarity index 100%
rename from asset/protos/asset_service.proto
rename to asset/google/cloud/asset_v1beta1/proto/asset_service.proto
diff --git a/asset/protos/assets.proto b/asset/google/cloud/asset_v1beta1/proto/assets.proto
similarity index 100%
rename from asset/protos/assets.proto
rename to asset/google/cloud/asset_v1beta1/proto/assets.proto
diff --git a/asset/synth.metadata b/asset/synth.metadata
index 911ae2cfe59d..52f95571ae76 100644
--- a/asset/synth.metadata
+++ b/asset/synth.metadata
@@ -1,5 +1,5 @@
 {
-  "updateTime": "2019-01-22T17:53:05.445272Z",
+  "updateTime": "2019-01-22T23:51:49.703550Z",
   "sources": [
     {
       "generator": {
@@ -12,8 +12,8 @@
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "96adaf6de4fa2cabbdd5de560a367bb488e0639b",
-        "internalRef": "229998977"
+        "sha": "33a4e6a0cfb3d0c4919c0978f914dccbcf8a671b",
+        "internalRef": "230421920"
       }
     },
     {
diff --git a/bigquery_datatransfer/google/cloud/bigquery_datatransfer_v1/proto/datatransfer.proto b/bigquery_datatransfer/google/cloud/bigquery_datatransfer_v1/proto/datatransfer.proto
new file mode 100644
index 000000000000..548256110ca9
--- /dev/null
+++ b/bigquery_datatransfer/google/cloud/bigquery_datatransfer_v1/proto/datatransfer.proto
@@ -0,0 +1,653 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.bigquery.datatransfer.v1;
+
+import "google/api/annotations.proto";
+import "google/cloud/bigquery/datatransfer/v1/transfer.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/wrappers.proto";
+
+option csharp_namespace = "Google.Cloud.BigQuery.DataTransfer.V1";
+option go_package = "google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1;datatransfer";
+option java_multiple_files = true;
+option java_outer_classname = "DataTransferProto";
+option java_package = "com.google.cloud.bigquery.datatransfer.v1";
+option php_namespace = "Google\\Cloud\\BigQuery\\DataTransfer\\V1";
+
+
+// The Google BigQuery Data Transfer Service API enables BigQuery users to
+// configure the transfer of their data from other Google Products into BigQuery.
+// This service contains methods that are end user exposed. It backs up the
+// frontend.
+service DataTransferService {
+  // Retrieves a supported data source and returns its settings,
+  // which can be used for UI rendering.
+  rpc GetDataSource(GetDataSourceRequest) returns (DataSource) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/dataSources/*}"
+      additional_bindings {
+        get: "/v1/{name=projects/*/dataSources/*}"
+      }
+    };
+  }
+
+  // Lists supported data sources and returns their settings,
+  // which can be used for UI rendering.
+  rpc ListDataSources(ListDataSourcesRequest) returns (ListDataSourcesResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/locations/*}/dataSources"
+      additional_bindings {
+        get: "/v1/{parent=projects/*}/dataSources"
+      }
+    };
+  }
+
+  // Creates a new data transfer configuration.
+  rpc CreateTransferConfig(CreateTransferConfigRequest) returns (TransferConfig) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/locations/*}/transferConfigs"
+      body: "transfer_config"
+      additional_bindings {
+        post: "/v1/{parent=projects/*}/transferConfigs"
+        body: "transfer_config"
+      }
+    };
+  }
+
+  // Updates a data transfer configuration.
+  // All fields must be set, even if they are not updated.
+  rpc UpdateTransferConfig(UpdateTransferConfigRequest) returns (TransferConfig) {
+    option (google.api.http) = {
+      patch: "/v1/{transfer_config.name=projects/*/locations/*/transferConfigs/*}"
+      body: "transfer_config"
+      additional_bindings {
+        patch: "/v1/{transfer_config.name=projects/*/transferConfigs/*}"
+        body: "transfer_config"
+      }
+    };
+  }
+
+  // Deletes a data transfer configuration,
+  // including any associated transfer runs and logs.
+  rpc DeleteTransferConfig(DeleteTransferConfigRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1/{name=projects/*/locations/*/transferConfigs/*}"
+      additional_bindings {
+        delete: "/v1/{name=projects/*/transferConfigs/*}"
+      }
+    };
+  }
+
+  // Returns information about a data transfer config.
+  rpc GetTransferConfig(GetTransferConfigRequest) returns (TransferConfig) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/transferConfigs/*}"
+      additional_bindings {
+        get: "/v1/{name=projects/*/transferConfigs/*}"
+      }
+    };
+  }
+
+  // Returns information about all data transfers in the project.
+  rpc ListTransferConfigs(ListTransferConfigsRequest) returns (ListTransferConfigsResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/locations/*}/transferConfigs"
+      additional_bindings {
+        get: "/v1/{parent=projects/*}/transferConfigs"
+      }
+    };
+  }
+
+  // Creates transfer runs for a time range [start_time, end_time].
+  // For each date - or whatever granularity the data source supports - in the
+  // range, one transfer run is created.
+  // Note that runs are created per UTC time in the time range.
+  rpc ScheduleTransferRuns(ScheduleTransferRunsRequest) returns (ScheduleTransferRunsResponse) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/locations/*/transferConfigs/*}:scheduleRuns"
+      body: "*"
+      additional_bindings {
+        post: "/v1/{parent=projects/*/transferConfigs/*}:scheduleRuns"
+        body: "*"
+      }
+    };
+  }
+
+  // Returns information about the particular transfer run.
+  rpc GetTransferRun(GetTransferRunRequest) returns (TransferRun) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/transferConfigs/*/runs/*}"
+      additional_bindings {
+        get: "/v1/{name=projects/*/transferConfigs/*/runs/*}"
+      }
+    };
+  }
+
+  // Deletes the specified transfer run.
+  rpc DeleteTransferRun(DeleteTransferRunRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1/{name=projects/*/locations/*/transferConfigs/*/runs/*}"
+      additional_bindings {
+        delete: "/v1/{name=projects/*/transferConfigs/*/runs/*}"
+      }
+    };
+  }
+
+  // Returns information about running and completed jobs.
+  rpc ListTransferRuns(ListTransferRunsRequest) returns (ListTransferRunsResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/locations/*/transferConfigs/*}/runs"
+      additional_bindings {
+        get: "/v1/{parent=projects/*/transferConfigs/*}/runs"
+      }
+    };
+  }
+
+  // Returns user facing log messages for the data transfer run.
+  rpc ListTransferLogs(ListTransferLogsRequest) returns (ListTransferLogsResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/locations/*/transferConfigs/*/runs/*}/transferLogs"
+      additional_bindings {
+        get: "/v1/{parent=projects/*/transferConfigs/*/runs/*}/transferLogs"
+      }
+    };
+  }
+
+  // Returns true if valid credentials exist for the given data source and
+  // requesting user.
+  // Some data sources doesn't support service account, so we need to talk to
+  // them on behalf of the end user. This API just checks whether we have OAuth
+  // token for the particular user, which is a pre-requisite before user can
+  // create a transfer config.
+  rpc CheckValidCreds(CheckValidCredsRequest) returns (CheckValidCredsResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/locations/*/dataSources/*}:checkValidCreds"
+      body: "*"
+      additional_bindings {
+        post: "/v1/{name=projects/*/dataSources/*}:checkValidCreds"
+        body: "*"
+      }
+    };
+  }
+}
+
+// Represents a data source parameter with validation rules, so that
+// parameters can be rendered in the UI. These parameters are given to us by
+// supported data sources, and include all needed information for rendering
+// and validation.
+// Thus, whoever uses this api can decide to generate either generic ui,
+// or custom data source specific forms.
+message DataSourceParameter {
+  // Parameter type.
+  enum Type {
+    // Type unspecified.
+    TYPE_UNSPECIFIED = 0;
+
+    // String parameter.
+    STRING = 1;
+
+    // Integer parameter (64-bits).
+    // Will be serialized to json as string.
+    INTEGER = 2;
+
+    // Double precision floating point parameter.
+    DOUBLE = 3;
+
+    // Boolean parameter.
+    BOOLEAN = 4;
+
+    // Record parameter.
+    RECORD = 5;
+
+    // Page ID for a Google+ Page.
+    PLUS_PAGE = 6;
+  }
+
+  // Parameter identifier.
+  string param_id = 1;
+
+  // Parameter display name in the user interface.
+  string display_name = 2;
+
+  // Parameter description.
+  string description = 3;
+
+  // Parameter type.
+  Type type = 4;
+
+  // Is parameter required.
+  bool required = 5;
+
+  // Can parameter have multiple values.
+  bool repeated = 6;
+
+  // Regular expression which can be used for parameter validation.
+  string validation_regex = 7;
+
+  // All possible values for the parameter.
+  repeated string allowed_values = 8;
+
+  // For integer and double values specifies minimum allowed value.
+  google.protobuf.DoubleValue min_value = 9;
+
+  // For integer and double values specifies maxminum allowed value.
+  google.protobuf.DoubleValue max_value = 10;
+
+  // When parameter is a record, describes child fields.
+  repeated DataSourceParameter fields = 11;
+
+  // Description of the requirements for this field, in case the user input does
+  // not fulfill the regex pattern or min/max values.
+  string validation_description = 12;
+
+  // URL to a help document to further explain the naming requirements.
+  string validation_help_url = 13;
+
+  // Cannot be changed after initial creation.
+  bool immutable = 14;
+
+  // If set to true, schema should be taken from the parent with the same
+  // parameter_id. Only applicable when parameter type is RECORD.
+  bool recurse = 15;
+}
+
+// Represents data source metadata. Metadata is sufficient to
+// render UI and request proper OAuth tokens.
+message DataSource {
+  // The type of authorization needed for this data source.
+  enum AuthorizationType {
+    // Type unspecified.
+    AUTHORIZATION_TYPE_UNSPECIFIED = 0;
+
+    // Use OAuth 2 authorization codes that can be exchanged
+    // for a refresh token on the backend.
+    AUTHORIZATION_CODE = 1;
+
+    // Return an authorization code for a given Google+ page that can then be
+    // exchanged for a refresh token on the backend.
+    GOOGLE_PLUS_AUTHORIZATION_CODE = 2;
+  }
+
+  // Represents how the data source supports data auto refresh.
+  enum DataRefreshType {
+    // The data source won't support data auto refresh, which is default value.
+    DATA_REFRESH_TYPE_UNSPECIFIED = 0;
+
+    // The data source supports data auto refresh, and runs will be scheduled
+    // for the past few days. Does not allow custom values to be set for each
+    // transfer config.
+    SLIDING_WINDOW = 1;
+
+    // The data source supports data auto refresh, and runs will be scheduled
+    // for the past few days. Allows custom values to be set for each transfer
+    // config.
+    CUSTOM_SLIDING_WINDOW = 2;
+  }
+
+  // Output only. Data source resource name.
+  string name = 1;
+
+  // Data source id.
+  string data_source_id = 2;
+
+  // User friendly data source name.
+  string display_name = 3;
+
+  // User friendly data source description string.
+  string description = 4;
+
+  // Data source client id which should be used to receive refresh token.
+  // When not supplied, no offline credentials are populated for data transfer.
+  string client_id = 5;
+
+  // Api auth scopes for which refresh token needs to be obtained. Only valid
+  // when `client_id` is specified. Ignored otherwise. These are scopes needed
+  // by a data source to prepare data and ingest them into BigQuery,
+  // e.g., https://www.googleapis.com/auth/bigquery
+  repeated string scopes = 6;
+
+  // Deprecated. This field has no effect.
+  TransferType transfer_type = 7;
+
+  // Indicates whether the data source supports multiple transfers
+  // to different BigQuery targets.
+  bool supports_multiple_transfers = 8;
+
+  // The number of seconds to wait for an update from the data source
+  // before BigQuery marks the transfer as failed.
+  int32 update_deadline_seconds = 9;
+
+  // Default data transfer schedule.
+  // Examples of valid schedules include:
+  // `1st,3rd monday of month 15:30`,
+  // `every wed,fri of jan,jun 13:15`, and
+  // `first sunday of quarter 00:00`.
+  string default_schedule = 10;
+
+  // Specifies whether the data source supports a user defined schedule, or
+  // operates on the default schedule.
+  // When set to `true`, user can override default schedule.
+  bool supports_custom_schedule = 11;
+
+  // Data source parameters.
+  repeated DataSourceParameter parameters = 12;
+
+  // Url for the help document for this data source.
+  string help_url = 13;
+
+  // Indicates the type of authorization.
+  AuthorizationType authorization_type = 14;
+
+  // Specifies whether the data source supports automatic data refresh for the
+  // past few days, and how it's supported.
+  // For some data sources, data might not be complete until a few days later,
+  // so it's useful to refresh data automatically.
+  DataRefreshType data_refresh_type = 15;
+
+  // Default data refresh window on days.
+  // Only meaningful when `data_refresh_type` = `SLIDING_WINDOW`.
+  int32 default_data_refresh_window_days = 16;
+
+  // Disables backfilling and manual run scheduling
+  // for the data source.
+  bool manual_runs_disabled = 17;
+
+  // The minimum interval for scheduler to schedule runs.
+  google.protobuf.Duration minimum_schedule_interval = 18;
+}
+
+// A request to get data source info.
+message GetDataSourceRequest {
+  // The field will contain name of the resource requested, for example:
+  // `projects/{project_id}/dataSources/{data_source_id}`
+  string name = 1;
+}
+
+// Request to list supported data sources and their data transfer settings.
+message ListDataSourcesRequest {
+  // The BigQuery project id for which data sources should be returned.
+  // Must be in the form: `projects/{project_id}`
+  string parent = 1;
+
+  // Pagination token, which can be used to request a specific page
+  // of `ListDataSourcesRequest` list results. For multiple-page
+  // results, `ListDataSourcesResponse` outputs
+  // a `next_page` token, which can be used as the
+  // `page_token` value to request the next page of list results.
+  string page_token = 3;
+
+  // Page size. The default page size is the maximum value of 1000 results.
+  int32 page_size = 4;
+}
+
+// Returns list of supported data sources and their metadata.
+message ListDataSourcesResponse {
+  // List of supported data sources and their transfer settings.
+  repeated DataSource data_sources = 1;
+
+  // Output only. The next-pagination token. For multiple-page list results,
+  // this token can be used as the
+  // `ListDataSourcesRequest.page_token`
+  // to request the next page of list results.
+  string next_page_token = 2;
+}
+
+// A request to create a data transfer configuration. If new credentials are
+// needed for this transfer configuration, an authorization code must be
+// provided. If an authorization code is provided, the transfer configuration
+// will be associated with the user id corresponding to the
+// authorization code. Otherwise, the transfer configuration will be associated
+// with the calling user.
+message CreateTransferConfigRequest {
+  // The BigQuery project id where the transfer configuration should be created.
+  // Must be in the format /projects/{project_id}/locations/{location_id}
+  // If specified location and location of the destination bigquery dataset
+  // do not match - the request will fail.
+  string parent = 1;
+
+  // Data transfer configuration to create.
+  TransferConfig transfer_config = 2;
+
+  // Optional OAuth2 authorization code to use with this transfer configuration.
+  // This is required if new credentials are needed, as indicated by
+  // `CheckValidCreds`.
+  // In order to obtain authorization_code, please make a
+  // request to
+  // https://www.gstatic.com/bigquerydatatransfer/oauthz/auth?client_id=<datatransferapiclientid>&scope=<data_source_scopes>&redirect_uri=<redirect_uri>
+  //
+  // * client_id should be OAuth client_id of BigQuery DTS API for the given
+  //   data source returned by ListDataSources method.
+  // * data_source_scopes are the scopes returned by ListDataSources method.
+  // * redirect_uri is an optional parameter. If not specified, then
+  //   authorization code is posted to the opener of authorization flow window.
+  //   Otherwise it will be sent to the redirect uri. A special value of
+  //   urn:ietf:wg:oauth:2.0:oob means that authorization code should be
+  //   returned in the title bar of the browser, with the page text prompting
+  //   the user to copy the code and paste it in the application.
+  string authorization_code = 3;
+}
+
+// A request to update a transfer configuration. To update the user id of the
+// transfer configuration, an authorization code needs to be provided.
+message UpdateTransferConfigRequest {
+  // Data transfer configuration to create.
+  TransferConfig transfer_config = 1;
+
+  // Optional OAuth2 authorization code to use with this transfer configuration.
+  // If it is provided, the transfer configuration will be associated with the
+  // authorizing user.
+  // In order to obtain authorization_code, please make a
+  // request to
+  // https://www.gstatic.com/bigquerydatatransfer/oauthz/auth?client_id=<datatransferapiclientid>&scope=<data_source_scopes>&redirect_uri=<redirect_uri>
+  //
+  // * client_id should be OAuth client_id of BigQuery DTS API for the given
+  //   data source returned by ListDataSources method.
+  // * data_source_scopes are the scopes returned by ListDataSources method.
+  // * redirect_uri is an optional parameter. If not specified, then
+  //   authorization code is posted to the opener of authorization flow window.
+  //   Otherwise it will be sent to the redirect uri. A special value of
+  //   urn:ietf:wg:oauth:2.0:oob means that authorization code should be
+  //   returned in the title bar of the browser, with the page text prompting
+  //   the user to copy the code and paste it in the application.
+  string authorization_code = 3;
+
+  // Required list of fields to be updated in this request.
+  google.protobuf.FieldMask update_mask = 4;
+}
+
+// A request to get data transfer information.
+message GetTransferConfigRequest {
+  // The field will contain name of the resource requested, for example:
+  // `projects/{project_id}/transferConfigs/{config_id}`
+  string name = 1;
+}
+
+// A request to delete data transfer information. All associated transfer runs
+// and log messages will be deleted as well.
+message DeleteTransferConfigRequest {
+  // The field will contain name of the resource requested, for example:
+  // `projects/{project_id}/transferConfigs/{config_id}`
+  string name = 1;
+}
+
+// A request to get data transfer run information.
+message GetTransferRunRequest {
+  // The field will contain name of the resource requested, for example:
+  // `projects/{project_id}/transferConfigs/{config_id}/runs/{run_id}`
+  string name = 1;
+}
+
+// A request to delete data transfer run information.
+message DeleteTransferRunRequest {
+  // The field will contain name of the resource requested, for example:
+  // `projects/{project_id}/transferConfigs/{config_id}/runs/{run_id}`
+  string name = 1;
+}
+
+// A request to list data transfers configured for a BigQuery project.
+message ListTransferConfigsRequest {
+  // The BigQuery project id for which data sources
+  // should be returned: `projects/{project_id}`.
+  string parent = 1;
+
+  // When specified, only configurations of requested data sources are returned.
+  repeated string data_source_ids = 2;
+
+  // Pagination token, which can be used to request a specific page
+  // of `ListTransfersRequest` list results. For multiple-page
+  // results, `ListTransfersResponse` outputs
+  // a `next_page` token, which can be used as the
+  // `page_token` value to request the next page of list results.
+  string page_token = 3;
+
+  // Page size. The default page size is the maximum value of 1000 results.
+  int32 page_size = 4;
+}
+
+// The returned list of pipelines in the project.
+message ListTransferConfigsResponse {
+  // Output only. The stored pipeline transfer configurations.
+  repeated TransferConfig transfer_configs = 1;
+
+  // Output only. The next-pagination token. For multiple-page list results,
+  // this token can be used as the
+  // `ListTransferConfigsRequest.page_token`
+  // to request the next page of list results.
+  string next_page_token = 2;
+}
+
+// A request to list data transfer runs. UI can use this method to show/filter
+// specific data transfer runs. The data source can use this method to request
+// all scheduled transfer runs.
+message ListTransferRunsRequest {
+  // Represents which runs should be pulled.
+  enum RunAttempt {
+    // All runs should be returned.
+    RUN_ATTEMPT_UNSPECIFIED = 0;
+
+    // Only latest run per day should be returned.
+    LATEST = 1;
+  }
+
+  // Name of transfer configuration for which transfer runs should be retrieved.
+  // Format of transfer configuration resource name is:
+  // `projects/{project_id}/transferConfigs/{config_id}`.
+  string parent = 1;
+
+  // When specified, only transfer runs with requested states are returned.
+  repeated TransferState states = 2;
+
+  // Pagination token, which can be used to request a specific page
+  // of `ListTransferRunsRequest` list results. For multiple-page
+  // results, `ListTransferRunsResponse` outputs
+  // a `next_page` token, which can be used as the
+  // `page_token` value to request the next page of list results.
+  string page_token = 3;
+
+  // Page size. The default page size is the maximum value of 1000 results.
+  int32 page_size = 4;
+
+  // Indicates how run attempts are to be pulled.
+  RunAttempt run_attempt = 5;
+}
+
+// The returned list of pipelines in the project.
+message ListTransferRunsResponse {
+  // Output only. The stored pipeline transfer runs.
+  repeated TransferRun transfer_runs = 1;
+
+  // Output only. The next-pagination token. For multiple-page list results,
+  // this token can be used as the
+  // `ListTransferRunsRequest.page_token`
+  // to request the next page of list results.
+  string next_page_token = 2;
+}
+
+// A request to get user facing log messages associated with data transfer run.
+message ListTransferLogsRequest {
+  // Transfer run name in the form:
+  // `projects/{project_id}/transferConfigs/{config_Id}/runs/{run_id}`.
+  string parent = 1;
+
+  // Pagination token, which can be used to request a specific page
+  // of `ListTransferLogsRequest` list results. For multiple-page
+  // results, `ListTransferLogsResponse` outputs
+  // a `next_page` token, which can be used as the
+  // `page_token` value to request the next page of list results.
+  string page_token = 4;
+
+  // Page size. The default page size is the maximum value of 1000 results.
+  int32 page_size = 5;
+
+  // Message types to return. If not populated - INFO, WARNING and ERROR
+  // messages are returned.
+  repeated TransferMessage.MessageSeverity message_types = 6;
+}
+
+// The returned list transfer run messages.
+message ListTransferLogsResponse {
+  // Output only. The stored pipeline transfer messages.
+  repeated TransferMessage transfer_messages = 1;
+
+  // Output only. The next-pagination token. For multiple-page list results,
+  // this token can be used as the
+  // `GetTransferRunLogRequest.page_token`
+  // to request the next page of list results.
+  string next_page_token = 2;
+}
+
+// A request to determine whether the user has valid credentials. This method
+// is used to limit the number of OAuth popups in the user interface. The
+// user id is inferred from the API call context.
+// If the data source has the Google+ authorization type, this method
+// returns false, as it cannot be determined whether the credentials are
+// already valid merely based on the user id.
+message CheckValidCredsRequest {
+  // The data source in the form:
+  // `projects/{project_id}/dataSources/{data_source_id}`
+  string name = 1;
+}
+
+// A response indicating whether the credentials exist and are valid.
+message CheckValidCredsResponse {
+  // If set to `true`, the credentials exist and are valid.
+  bool has_valid_creds = 1;
+}
+
+// A request to schedule transfer runs for a time range.
+message ScheduleTransferRunsRequest {
+  // Transfer configuration name in the form:
+  // `projects/{project_id}/transferConfigs/{config_id}`.
+  string parent = 1;
+
+  // Start time of the range of transfer runs. For example,
+  // `"2017-05-25T00:00:00+00:00"`.
+  google.protobuf.Timestamp start_time = 2;
+
+  // End time of the range of transfer runs. For example,
+  // `"2017-05-30T00:00:00+00:00"`.
+  google.protobuf.Timestamp end_time = 3;
+}
+
+// A response to schedule transfer runs for a time range.
+message ScheduleTransferRunsResponse {
+  // The transfer runs that were scheduled.
+  repeated TransferRun runs = 1;
+}
diff --git a/bigquery_datatransfer/google/cloud/bigquery_datatransfer_v1/proto/transfer.proto b/bigquery_datatransfer/google/cloud/bigquery_datatransfer_v1/proto/transfer.proto
new file mode 100644
index 000000000000..0cadeed5b9d1
--- /dev/null
+++ b/bigquery_datatransfer/google/cloud/bigquery_datatransfer_v1/proto/transfer.proto
@@ -0,0 +1,222 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.bigquery.datatransfer.v1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.BigQuery.DataTransfer.V1";
+option go_package = "google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1;datatransfer";
+option java_multiple_files = true;
+option java_outer_classname = "TransferProto";
+option java_package = "com.google.cloud.bigquery.datatransfer.v1";
+option objc_class_prefix = "GCBDT";
+option php_namespace = "Google\\Cloud\\BigQuery\\DataTransfer\\V1";
+
+
+// Represents a data transfer configuration. A transfer configuration
+// contains all metadata needed to perform a data transfer. For example,
+// `destination_dataset_id` specifies where data should be stored.
+// When a new transfer configuration is created, the specified
+// `destination_dataset_id` is created when needed and shared with the
+// appropriate data source service account.
+message TransferConfig {
+  // The resource name of the transfer config.
+  // Transfer config names have the form
+  // `projects/{project_id}/transferConfigs/{config_id}`.
+  // Where `config_id` is usually a uuid, even though it is not
+  // guaranteed or required. The name is ignored when creating a transfer
+  // config.
+  string name = 1;
+
+  // The BigQuery target dataset id.
+  string destination_dataset_id = 2;
+
+  // User specified display name for the data transfer.
+  string display_name = 3;
+
+  // Data source id. Cannot be changed once data transfer is created.
+  string data_source_id = 5;
+
+  // Data transfer specific parameters.
+  google.protobuf.Struct params = 9;
+
+  // Data transfer schedule.
+  // If the data source does not support a custom schedule, this should be
+  // empty. If it is empty, the default value for the data source will be
+  // used.
+  // The specified times are in UTC.
+  // Examples of valid format:
+  // `1st,3rd monday of month 15:30`,
+  // `every wed,fri of jan,jun 13:15`, and
+  // `first sunday of quarter 00:00`.
+  // See more explanation about the format here:
+  // https://cloud.google.com/appengine/docs/flexible/python/scheduling-jobs-with-cron-yaml#the_schedule_format
+  // NOTE: the granularity should be at least 8 hours, or less frequent.
+  string schedule = 7;
+
+  // The number of days to look back to automatically refresh the data.
+  // For example, if `data_refresh_window_days = 10`, then every day
+  // BigQuery reingests data for [today-10, today-1], rather than ingesting data
+  // for just [today-1].
+  // Only valid if the data source supports the feature. Set the value to  0
+  // to use the default value.
+  int32 data_refresh_window_days = 12;
+
+  // Is this config disabled. When set to true, no runs are scheduled
+  // for a given transfer.
+  bool disabled = 13;
+
+  // Output only. Data transfer modification time. Ignored by server on input.
+  google.protobuf.Timestamp update_time = 4;
+
+  // Output only. Next time when data transfer will run.
+  google.protobuf.Timestamp next_run_time = 8;
+
+  // Output only. State of the most recently updated transfer run.
+  TransferState state = 10;
+
+  // Output only. Unique ID of the user on whose behalf transfer is done.
+  // Applicable only to data sources that do not support service accounts.
+  // When set to 0, the data source service account credentials are used.
+  // May be negative. Note, that this identifier is not stable.
+  // It may change over time even for the same user.
+  int64 user_id = 11;
+
+  // Output only. Region in which BigQuery dataset is located.
+  string dataset_region = 14;
+}
+
+// Represents a data transfer run.
+message TransferRun {
+  // The resource name of the transfer run.
+  // Transfer run names have the form
+  // `projects/{project_id}/locations/{location}/transferConfigs/{config_id}/runs/{run_id}`.
+  // The name is ignored when creating a transfer run.
+  string name = 1;
+
+  // Minimum time after which a transfer run can be started.
+  google.protobuf.Timestamp schedule_time = 3;
+
+  // For batch transfer runs, specifies the date and time that
+  // data should be ingested.
+  google.protobuf.Timestamp run_time = 10;
+
+  // Status of the transfer run.
+  google.rpc.Status error_status = 21;
+
+  // Output only. Time when transfer run was started.
+  // Parameter ignored by server for input requests.
+  google.protobuf.Timestamp start_time = 4;
+
+  // Output only. Time when transfer run ended.
+  // Parameter ignored by server for input requests.
+  google.protobuf.Timestamp end_time = 5;
+
+  // Output only. Last time the data transfer run state was updated.
+  google.protobuf.Timestamp update_time = 6;
+
+  // Output only. Data transfer specific parameters.
+  google.protobuf.Struct params = 9;
+
+  // Output only. The BigQuery target dataset id.
+  string destination_dataset_id = 2;
+
+  // Output only. Data source id.
+  string data_source_id = 7;
+
+  // Data transfer run state. Ignored for input requests.
+  TransferState state = 8;
+
+  // Output only. Unique ID of the user on whose behalf transfer is done.
+  // Applicable only to data sources that do not support service accounts.
+  // When set to 0, the data source service account credentials are used.
+  // May be negative. Note, that this identifier is not stable.
+  // It may change over time even for the same user.
+  int64 user_id = 11;
+
+  // Output only. Describes the schedule of this transfer run if it was
+  // created as part of a regular schedule. For batch transfer runs that are
+  // scheduled manually, this is empty.
+  // NOTE: the system might choose to delay the schedule depending on the
+  // current load, so `schedule_time` doesn't always matches this.
+  string schedule = 12;
+}
+
+// Represents a user facing message for a particular data transfer run.
+message TransferMessage {
+  // Represents data transfer user facing message severity.
+  enum MessageSeverity {
+    // No severity specified.
+    MESSAGE_SEVERITY_UNSPECIFIED = 0;
+
+    // Informational message.
+    INFO = 1;
+
+    // Warning message.
+    WARNING = 2;
+
+    // Error message.
+    ERROR = 3;
+  }
+
+  // Time when message was logged.
+  google.protobuf.Timestamp message_time = 1;
+
+  // Message severity.
+  MessageSeverity severity = 2;
+
+  // Message text.
+  string message_text = 3;
+}
+
+// DEPRECATED. Represents data transfer type.
+enum TransferType {
+  // Invalid or Unknown transfer type placeholder.
+  TRANSFER_TYPE_UNSPECIFIED = 0;
+
+  // Batch data transfer.
+  BATCH = 1;
+
+  // Streaming data transfer. Streaming data source currently doesn't
+  // support multiple transfer configs per project.
+  STREAMING = 2;
+}
+
+// Represents data transfer run state.
+enum TransferState {
+  // State placeholder.
+  TRANSFER_STATE_UNSPECIFIED = 0;
+
+  // Data transfer is scheduled and is waiting to be picked up by
+  // data transfer backend.
+  PENDING = 2;
+
+  // Data transfer is in progress.
+  RUNNING = 3;
+
+  // Data transfer completed successsfully.
+  SUCCEEDED = 4;
+
+  // Data transfer failed.
+  FAILED = 5;
+
+  // Data transfer is cancelled.
+  CANCELLED = 6;
+}
diff --git a/bigquery_datatransfer/synth.metadata b/bigquery_datatransfer/synth.metadata
index a3781caccd3a..45829dbc8457 100644
--- a/bigquery_datatransfer/synth.metadata
+++ b/bigquery_datatransfer/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:12:30.477136Z",
+  "updateTime": "2019-01-23T22:00:39.365486Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
@@ -28,7 +28,7 @@
     {
       "client": {
         "source": "googleapis",
-        "apiName": "bigquery-datatransfer",
+        "apiName": "bigquery_datatransfer",
         "apiVersion": "v1",
         "language": "python",
         "generator": "gapic",
diff --git a/bigquery_datatransfer/synth.py b/bigquery_datatransfer/synth.py
index 290bdcbfb8e2..b569d54cd4e0 100644
--- a/bigquery_datatransfer/synth.py
+++ b/bigquery_datatransfer/synth.py
@@ -25,11 +25,12 @@
 # Generate bigquery_datatransfer GAPIC layer
 # ----------------------------------------------------------------------------
 library = gapic.py_library(
-    "bigquery-datatransfer",
+    "bigquery_datatransfer",
     version,
     config_path="/google/cloud/bigquery/datatransfer/"
     "artman_bigquerydatatransfer.yaml",
     artman_output_name="bigquerydatatransfer-v1",
+    include_protos=True,
 )
 
 s.move(
diff --git a/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/avro.proto b/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/avro.proto
new file mode 100644
index 000000000000..b75de8f266f1
--- /dev/null
+++ b/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/avro.proto
@@ -0,0 +1,39 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.bigquery.storage.v1beta1;
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1;storage";
+option java_outer_classname = "AvroProto";
+option java_package = "com.google.cloud.bigquery.storage.v1beta1";
+
+
+// Avro schema.
+message AvroSchema {
+  // Json serialized schema, as described at
+  // https://avro.apache.org/docs/1.8.1/spec.html
+  string schema = 1;
+}
+
+// Avro rows.
+message AvroRows {
+  // Binary serialized rows in a block.
+  bytes serialized_binary_rows = 1;
+
+  // The count of rows in the returning block.
+  int64 row_count = 2;
+}
diff --git a/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/read_options.proto b/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/read_options.proto
new file mode 100644
index 000000000000..84307ce475e9
--- /dev/null
+++ b/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/read_options.proto
@@ -0,0 +1,39 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.bigquery.storage.v1beta1;
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1;storage";
+option java_package = "com.google.cloud.bigquery.storage.v1beta1";
+
+
+// Options dictating how we read a table.
+message TableReadOptions {
+  // Optional. Names of the fields in the table that should be read. If empty,
+  // all fields will be read. If the specified field is a nested field, all the
+  // sub-fields in the field will be selected. The output field order is
+  // unrelated to the order of fields in selected_fields.
+  repeated string selected_fields = 1;
+
+  // Optional. SQL text filtering statement, similar to a WHERE clause in
+  // a query. Currently, we support combinations of predicates that are
+  // a comparison between a column and a constant value in SQL statement.
+  // Aggregates are not supported.
+  //
+  // Example: "a > DATE '2014-9-27' AND (b > 5 and C LIKE 'date')"
+  string row_restriction = 2;
+}
diff --git a/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/storage.proto b/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/storage.proto
new file mode 100644
index 000000000000..7396355f0ed5
--- /dev/null
+++ b/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/storage.proto
@@ -0,0 +1,268 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.bigquery.storage.v1beta1;
+
+import "google/cloud/bigquery/storage/v1beta1/avro.proto";
+import "google/cloud/bigquery/storage/v1beta1/read_options.proto";
+import "google/cloud/bigquery/storage/v1beta1/table_reference.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1;storage";
+option java_package = "com.google.cloud.bigquery.storage.v1beta1";
+
+
+// BigQuery storage API.
+//
+// The BigQuery storage API can be used to read data stored in BigQuery.
+service BigQueryStorage {
+  // Creates a new read session. A read session divides the contents of a
+  // BigQuery table into one or more streams, which can then be used to read
+  // data from the table. The read session also specifies properties of the
+  // data to be read, such as a list of columns or a push-down filter describing
+  // the rows to be returned.
+  //
+  // A particular row can be read by at most one stream. When the caller has
+  // reached the end of each stream in the session, then all the data in the
+  // table has been read.
+  //
+  // Read sessions automatically expire 24 hours after they are created and do
+  // not require manual clean-up by the caller.
+  rpc CreateReadSession(CreateReadSessionRequest) returns (ReadSession) {
+  }
+
+  // Reads rows from the table in the format prescribed by the read session.
+  // Each response contains one or more table rows, up to a maximum of 10 MiB
+  // per response; read requests which attempt to read individual rows larger
+  // than this will fail.
+  //
+  // Each request also returns a set of stream statistics reflecting the
+  // estimated total number of rows in the read stream. This number is computed
+  // based on the total table size and the number of active streams in the read
+  // session, and may change as other streams continue to read data.
+  rpc ReadRows(ReadRowsRequest) returns (stream ReadRowsResponse) {
+  }
+
+  // Creates additional streams for a ReadSession. This API can be used to
+  // dynamically adjust the parallelism of a batch processing task upwards by
+  // adding additional workers.
+  rpc BatchCreateReadSessionStreams(BatchCreateReadSessionStreamsRequest) returns (BatchCreateReadSessionStreamsResponse) {
+  }
+
+  // Triggers the graceful termination of a single stream in a ReadSession. This
+  // API can be used to dynamically adjust the parallelism of a batch processing
+  // task downwards without losing data.
+  //
+  // This API does not delete the stream -- it remains visible in the
+  // ReadSession, and any data processed by the stream is not released to other
+  // streams. However, no additional data will be assigned to the stream once
+  // this call completes. Callers must continue reading data on the stream until
+  // the end of the stream is reached so that data which has already been
+  // assigned to the stream will be processed.
+  //
+  // This method will return an error if there are no other live streams
+  // in the Session, or if SplitReadStream() has been called on the given
+  // Stream.
+  rpc FinalizeStream(FinalizeStreamRequest) returns (google.protobuf.Empty) {
+  }
+
+  // Splits a given read stream into two Streams. These streams are referred to
+  // as the primary and the residual of the split. The original stream can still
+  // be read from in the same manner as before. Both of the returned streams can
+  // also be read from, and the total rows return by both child streams will be
+  // the same as the rows read from the original stream.
+  //
+  // Moreover, the two child streams will be allocated back to back in the
+  // original Stream. Concretely, it is guaranteed that for streams Original,
+  // Primary, and Residual, that Original[0-j] = Primary[0-j] and
+  // Original[j-n] = Residual[0-m] once the streams have been read to
+  // completion.
+  //
+  // This method is guaranteed to be idempotent.
+  rpc SplitReadStream(SplitReadStreamRequest) returns (SplitReadStreamResponse) {
+  }
+}
+
+// Information about a single data stream within a read session.
+message Stream {
+  // Name of the stream. In the form
+  // `/projects/{project_id}/stream/{stream_id}`
+  string name = 1;
+
+  // Rows in the stream.
+  int64 row_count = 2;
+}
+
+// Expresses a point within a given stream using an offset position.
+message StreamPosition {
+  // Identifier for a given Stream.
+  Stream stream = 1;
+
+  // Position in the stream.
+  int64 offset = 2;
+}
+
+// Information returned from a `CreateReadSession` request.
+message ReadSession {
+  // Unique identifier for the session. In the form
+  // `projects/{project_id}/sessions/{session_id}`
+  string name = 1;
+
+  // Time at which the session becomes invalid. After this time, subsequent
+  // requests to read this Session will return errors.
+  google.protobuf.Timestamp expire_time = 2;
+
+  // The schema for the read. If read_options.selected_fields is set, the
+  // schema may be different from the table schema as it will only contain
+  // the selected fields.
+  oneof schema {
+    // Avro schema.
+    AvroSchema avro_schema = 5;
+  }
+
+  // Streams associated with this session.
+  repeated Stream streams = 4;
+
+  // Table that this ReadSession is reading from.
+  TableReference table_reference = 7;
+
+  // Any modifiers which are applied when reading from the specified table.
+  TableModifiers table_modifiers = 8;
+}
+
+// Creates a new read session, which may include additional options such as
+// requested parallelism, projection filters and constraints.
+message CreateReadSessionRequest {
+  // Required. Reference to the table to read.
+  TableReference table_reference = 1;
+
+  // Required. String of the form "projects/your-project-id" indicating the
+  // project this ReadSession is associated with. This is the project that will
+  // be billed for usage.
+  string parent = 6;
+
+  // Optional. Any modifiers to the Table (e.g. snapshot timestamp).
+  TableModifiers table_modifiers = 2;
+
+  // Optional. Initial number of streams. If unset or 0, we will
+  // provide a value of streams so as to produce reasonable throughput. Must be
+  // non-negative. The number of streams may be lower than the requested number,
+  // depending on the amount parallelism that is reasonable for the table and
+  // the maximum amount of parallelism allowed by the system.
+  //
+  // Streams must be read starting from offset 0.
+  int32 requested_streams = 3;
+
+  // Optional. Read options for this session (e.g. column selection, filters).
+  TableReadOptions read_options = 4;
+
+  // Data output format. Currently default to Avro.
+  DataFormat format = 5;
+}
+
+// Requesting row data via `ReadRows` must provide Stream position information.
+message ReadRowsRequest {
+  // Required. Identifier of the position in the stream to start reading from.
+  // The offset requested must be less than the last row read from ReadRows.
+  // Requesting a larger offset is undefined.
+  StreamPosition read_position = 1;
+}
+
+// Progress information for a given Stream.
+message StreamStatus {
+  // Number of estimated rows in the current stream. May change over time as
+  // different readers in the stream progress at rates which are relatively fast
+  // or slow.
+  int64 estimated_row_count = 1;
+}
+
+// Information on if the current connection is being throttled.
+message ThrottleStatus {
+  // How much this connection is being throttled.
+  // 0 is no throttling, 100 is completely throttled.
+  int32 throttle_percent = 1;
+}
+
+// Response from calling `ReadRows` may include row data, progress and
+// throttling information.
+message ReadRowsResponse {
+  // Row data is returned in format specified during session creation.
+  oneof rows {
+    // Serialized row data in AVRO format.
+    AvroRows avro_rows = 3;
+  }
+
+  // Estimated stream statistics.
+  StreamStatus status = 2;
+
+  // Throttling status. If unset, the latest response still describes
+  // the current throttling status.
+  ThrottleStatus throttle_status = 5;
+}
+
+// Information needed to request additional streams for an established read
+// session.
+message BatchCreateReadSessionStreamsRequest {
+  // Required. Must be a non-expired session obtained from a call to
+  // CreateReadSession. Only the name field needs to be set.
+  ReadSession session = 1;
+
+  // Required. Number of new streams requested. Must be positive.
+  // Number of added streams may be less than this, see CreateReadSessionRequest
+  // for more information.
+  int32 requested_streams = 2;
+}
+
+// The response from `BatchCreateReadSessionStreams` returns the stream
+// identifiers for the newly created streams.
+message BatchCreateReadSessionStreamsResponse {
+  // Newly added streams.
+  repeated Stream streams = 1;
+}
+
+// Request information for invoking `FinalizeStream`.
+message FinalizeStreamRequest {
+  // Stream to finalize.
+  Stream stream = 2;
+}
+
+// Request information for `SplitReadStream`.
+message SplitReadStreamRequest {
+  // Stream to split.
+  Stream original_stream = 1;
+}
+
+// Response from `SplitReadStream`.
+message SplitReadStreamResponse {
+  // Primary stream. Will contain the beginning portion of
+  // |original_stream|.
+  Stream primary_stream = 1;
+
+  // Remainder stream. Will contain the tail of |original_stream|.
+  Stream remainder_stream = 2;
+}
+
+// Data format for input or output data.
+enum DataFormat {
+  // Data format is unspecified.
+  DATA_FORMAT_UNSPECIFIED = 0;
+
+  // Avro is a standard open source row based file format.
+  // See https://avro.apache.org/ for more details.
+  AVRO = 1;
+}
diff --git a/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/table_reference.proto b/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/table_reference.proto
new file mode 100644
index 000000000000..a493fac91b0e
--- /dev/null
+++ b/bigquery_storage/google/cloud/bigquery_storage_v1beta1/proto/table_reference.proto
@@ -0,0 +1,43 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.bigquery.storage.v1beta1;
+
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1;storage";
+option java_outer_classname = "TableReferenceProto";
+option java_package = "com.google.cloud.bigquery.storage.v1beta1";
+
+
+// Table reference that includes just the 3 strings needed to identify a table.
+message TableReference {
+  // The assigned project ID of the project.
+  string project_id = 1;
+
+  // The ID of the dataset in the above project.
+  string dataset_id = 2;
+
+  // The ID of the table in the above dataset.
+  string table_id = 3;
+}
+
+// All fields in this message optional.
+message TableModifiers {
+  // The snapshot time of the table. If not set, interpreted as now.
+  google.protobuf.Timestamp snapshot_time = 1;
+}
diff --git a/bigquery_storage/synth.metadata b/bigquery_storage/synth.metadata
index d037a81b1dd8..c93976bff7b9 100644
--- a/bigquery_storage/synth.metadata
+++ b/bigquery_storage/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:12:58.682614Z",
+  "updateTime": "2019-01-23T22:34:59.128047Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     }
   ],
@@ -21,8 +21,8 @@
     {
       "client": {
         "source": "googleapis",
-        "apiName": "bigquery-datatransfer",
-        "apiVersion": "v1",
+        "apiName": "bigquery_storage",
+        "apiVersion": "v1beta1",
         "language": "python",
         "generator": "gapic",
         "config": "google/cloud/bigquery/storage/artman_bigquerystorage_v1beta1.yaml"
diff --git a/bigquery_storage/synth.py b/bigquery_storage/synth.py
index c688789014f5..bd3247eb6d5f 100644
--- a/bigquery_storage/synth.py
+++ b/bigquery_storage/synth.py
@@ -19,14 +19,15 @@
 
 gapic = gcp.GAPICGenerator()
 
-version = 'v1'
+version = 'v1beta1'
 
 library = gapic.py_library(
-    'bigquery-datatransfer',
+    'bigquery_storage',
     version,
     config_path='/google/cloud/bigquery/storage/'
                 'artman_bigquerystorage_v1beta1.yaml',
-    artman_output_name='bigquerystorage-v1beta1'
+    artman_output_name='bigquerystorage-v1beta1',
+    include_protos=True,
 )
 
 s.move(
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_cluster_data.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_cluster_data.proto
new file mode 100644
index 000000000000..ca3b663d8661
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_cluster_data.proto
@@ -0,0 +1,94 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.cluster.v1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1;cluster";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableClusterDataProto";
+option java_package = "com.google.bigtable.admin.cluster.v1";
+
+
+// A physical location in which a particular project can allocate Cloud BigTable
+// resources.
+message Zone {
+  // Possible states of a zone.
+  enum Status {
+    // The state of the zone is unknown or unspecified.
+    UNKNOWN = 0;
+
+    // The zone is in a good state.
+    OK = 1;
+
+    // The zone is down for planned maintenance.
+    PLANNED_MAINTENANCE = 2;
+
+    // The zone is down for emergency or unplanned maintenance.
+    EMERGENCY_MAINENANCE = 3;
+  }
+
+  // A permanent unique identifier for the zone.
+  // Values are of the form projects/<project>/zones/[a-z][-a-z0-9]*
+  string name = 1;
+
+  // The name of this zone as it appears in UIs.
+  string display_name = 2;
+
+  // The current state of this zone.
+  Status status = 3;
+}
+
+// An isolated set of Cloud BigTable resources on which tables can be hosted.
+message Cluster {
+  // A permanent unique identifier for the cluster. For technical reasons, the
+  // zone in which the cluster resides is included here.
+  // Values are of the form
+  // projects/<project>/zones/<zone>/clusters/[a-z][-a-z0-9]*
+  string name = 1;
+
+  // The operation currently running on the cluster, if any.
+  // This cannot be set directly, only through CreateCluster, UpdateCluster,
+  // or UndeleteCluster. Calls to these methods will be rejected if
+  // "current_operation" is already set.
+  google.longrunning.Operation current_operation = 3;
+
+  // The descriptive name for this cluster as it appears in UIs.
+  // Must be unique per zone.
+  string display_name = 4;
+
+  // The number of serve nodes allocated to this cluster.
+  int32 serve_nodes = 5;
+
+  // What storage type to use for tables in this cluster. Only configurable at
+  // cluster creation time. If unspecified, STORAGE_SSD will be used.
+  StorageType default_storage_type = 8;
+}
+
+enum StorageType {
+  // The storage type used is unspecified.
+  STORAGE_UNSPECIFIED = 0;
+
+  // Data will be stored in SSD, providing low and consistent latencies.
+  STORAGE_SSD = 1;
+
+  // Data will be stored in HDD, providing high and less predictable
+  // latencies.
+  STORAGE_HDD = 2;
+}
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_cluster_service.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_cluster_service.proto
new file mode 100644
index 000000000000..038fcc46397f
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_cluster_service.proto
@@ -0,0 +1,130 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.cluster.v1;
+
+import "google/api/annotations.proto";
+import "google/bigtable/admin/cluster/v1/bigtable_cluster_data.proto";
+import "google/bigtable/admin/cluster/v1/bigtable_cluster_service_messages.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1;cluster";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableClusterServicesProto";
+option java_package = "com.google.bigtable.admin.cluster.v1";
+
+
+// Service for managing zonal Cloud Bigtable resources.
+service BigtableClusterService {
+  // Lists the supported zones for the given project.
+  rpc ListZones(ListZonesRequest) returns (ListZonesResponse) {
+    option (google.api.http) = { get: "/v1/{name=projects/*}/zones" };
+  }
+
+  // Gets information about a particular cluster.
+  rpc GetCluster(GetClusterRequest) returns (Cluster) {
+    option (google.api.http) = { get: "/v1/{name=projects/*/zones/*/clusters/*}" };
+  }
+
+  // Lists all clusters in the given project, along with any zones for which
+  // cluster information could not be retrieved.
+  rpc ListClusters(ListClustersRequest) returns (ListClustersResponse) {
+    option (google.api.http) = { get: "/v1/{name=projects/*}/aggregated/clusters" };
+  }
+
+  // Creates a cluster and begins preparing it to begin serving. The returned
+  // cluster embeds as its "current_operation" a long-running operation which
+  // can be used to track the progress of turning up the new cluster.
+  // Immediately upon completion of this request:
+  //  * The cluster will be readable via the API, with all requested attributes
+  //    but no allocated resources.
+  // Until completion of the embedded operation:
+  //  * Cancelling the operation will render the cluster immediately unreadable
+  //    via the API.
+  //  * All other attempts to modify or delete the cluster will be rejected.
+  // Upon completion of the embedded operation:
+  //  * Billing for all successfully-allocated resources will begin (some types
+  //    may have lower than the requested levels).
+  //  * New tables can be created in the cluster.
+  //  * The cluster's allocated resource levels will be readable via the API.
+  // The embedded operation's "metadata" field type is
+  // [CreateClusterMetadata][google.bigtable.admin.cluster.v1.CreateClusterMetadata] The embedded operation's "response" field type is
+  // [Cluster][google.bigtable.admin.cluster.v1.Cluster], if successful.
+  rpc CreateCluster(CreateClusterRequest) returns (Cluster) {
+    option (google.api.http) = { post: "/v1/{name=projects/*/zones/*}/clusters" body: "*" };
+  }
+
+  // Updates a cluster, and begins allocating or releasing resources as
+  // requested. The returned cluster embeds as its "current_operation" a
+  // long-running operation which can be used to track the progress of updating
+  // the cluster.
+  // Immediately upon completion of this request:
+  //  * For resource types where a decrease in the cluster's allocation has been
+  //    requested, billing will be based on the newly-requested level.
+  // Until completion of the embedded operation:
+  //  * Cancelling the operation will set its metadata's "cancelled_at_time",
+  //    and begin restoring resources to their pre-request values. The operation
+  //    is guaranteed to succeed at undoing all resource changes, after which
+  //    point it will terminate with a CANCELLED status.
+  //  * All other attempts to modify or delete the cluster will be rejected.
+  //  * Reading the cluster via the API will continue to give the pre-request
+  //    resource levels.
+  // Upon completion of the embedded operation:
+  //  * Billing will begin for all successfully-allocated resources (some types
+  //    may have lower than the requested levels).
+  //  * All newly-reserved resources will be available for serving the cluster's
+  //    tables.
+  //  * The cluster's new resource levels will be readable via the API.
+  // [UpdateClusterMetadata][google.bigtable.admin.cluster.v1.UpdateClusterMetadata] The embedded operation's "response" field type is
+  // [Cluster][google.bigtable.admin.cluster.v1.Cluster], if successful.
+  rpc UpdateCluster(Cluster) returns (Cluster) {
+    option (google.api.http) = { put: "/v1/{name=projects/*/zones/*/clusters/*}" body: "*" };
+  }
+
+  // Marks a cluster and all of its tables for permanent deletion in 7 days.
+  // Immediately upon completion of the request:
+  //  * Billing will cease for all of the cluster's reserved resources.
+  //  * The cluster's "delete_time" field will be set 7 days in the future.
+  // Soon afterward:
+  //  * All tables within the cluster will become unavailable.
+  // Prior to the cluster's "delete_time":
+  //  * The cluster can be recovered with a call to UndeleteCluster.
+  //  * All other attempts to modify or delete the cluster will be rejected.
+  // At the cluster's "delete_time":
+  //  * The cluster and *all of its tables* will immediately and irrevocably
+  //    disappear from the API, and their data will be permanently deleted.
+  rpc DeleteCluster(DeleteClusterRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { delete: "/v1/{name=projects/*/zones/*/clusters/*}" };
+  }
+
+  // Cancels the scheduled deletion of an cluster and begins preparing it to
+  // resume serving. The returned operation will also be embedded as the
+  // cluster's "current_operation".
+  // Immediately upon completion of this request:
+  //  * The cluster's "delete_time" field will be unset, protecting it from
+  //    automatic deletion.
+  // Until completion of the returned operation:
+  //  * The operation cannot be cancelled.
+  // Upon completion of the returned operation:
+  //  * Billing for the cluster's resources will resume.
+  //  * All tables within the cluster will be available.
+  // [UndeleteClusterMetadata][google.bigtable.admin.cluster.v1.UndeleteClusterMetadata] The embedded operation's "response" field type is
+  // [Cluster][google.bigtable.admin.cluster.v1.Cluster], if successful.
+  rpc UndeleteCluster(UndeleteClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = { post: "/v1/{name=projects/*/zones/*/clusters/*}:undelete" body: "" };
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_cluster_service_messages.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_cluster_service_messages.proto
new file mode 100644
index 000000000000..518d14dac8e0
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_cluster_service_messages.proto
@@ -0,0 +1,141 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.cluster.v1;
+
+import "google/bigtable/admin/cluster/v1/bigtable_cluster_data.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1;cluster";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableClusterServiceMessagesProto";
+option java_package = "com.google.bigtable.admin.cluster.v1";
+
+
+// Request message for BigtableClusterService.ListZones.
+message ListZonesRequest {
+  // The unique name of the project for which a list of supported zones is
+  // requested.
+  // Values are of the form projects/<project>
+  string name = 1;
+}
+
+// Response message for BigtableClusterService.ListZones.
+message ListZonesResponse {
+  // The list of requested zones.
+  repeated Zone zones = 1;
+}
+
+// Request message for BigtableClusterService.GetCluster.
+message GetClusterRequest {
+  // The unique name of the requested cluster.
+  // Values are of the form projects/<project>/zones/<zone>/clusters/<cluster>
+  string name = 1;
+}
+
+// Request message for BigtableClusterService.ListClusters.
+message ListClustersRequest {
+  // The unique name of the project for which a list of clusters is requested.
+  // Values are of the form projects/<project>
+  string name = 1;
+}
+
+// Response message for BigtableClusterService.ListClusters.
+message ListClustersResponse {
+  // The list of requested Clusters.
+  repeated Cluster clusters = 1;
+
+  // The zones for which clusters could not be retrieved.
+  repeated Zone failed_zones = 2;
+}
+
+// Request message for BigtableClusterService.CreateCluster.
+message CreateClusterRequest {
+  // The unique name of the zone in which to create the cluster.
+  // Values are of the form projects/<project>/zones/<zone>
+  string name = 1;
+
+  // The id to be used when referring to the new cluster within its zone,
+  // e.g. just the "test-cluster" section of the full name
+  // "projects/<project>/zones/<zone>/clusters/test-cluster".
+  string cluster_id = 2;
+
+  // The cluster to create.
+  // The "name", "delete_time", and "current_operation" fields must be left
+  // blank.
+  Cluster cluster = 3;
+}
+
+// Metadata type for the operation returned by
+// BigtableClusterService.CreateCluster.
+message CreateClusterMetadata {
+  // The request which prompted the creation of this operation.
+  CreateClusterRequest original_request = 1;
+
+  // The time at which original_request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which this operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// Metadata type for the operation returned by
+// BigtableClusterService.UpdateCluster.
+message UpdateClusterMetadata {
+  // The request which prompted the creation of this operation.
+  Cluster original_request = 1;
+
+  // The time at which original_request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which this operation was cancelled. If set, this operation is
+  // in the process of undoing itself (which is guaranteed to succeed) and
+  // cannot be cancelled again.
+  google.protobuf.Timestamp cancel_time = 3;
+
+  // The time at which this operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 4;
+}
+
+// Request message for BigtableClusterService.DeleteCluster.
+message DeleteClusterRequest {
+  // The unique name of the cluster to be deleted.
+  // Values are of the form projects/<project>/zones/<zone>/clusters/<cluster>
+  string name = 1;
+}
+
+// Request message for BigtableClusterService.UndeleteCluster.
+message UndeleteClusterRequest {
+  // The unique name of the cluster to be un-deleted.
+  // Values are of the form projects/<project>/zones/<zone>/clusters/<cluster>
+  string name = 1;
+}
+
+// Metadata type for the operation returned by
+// BigtableClusterService.UndeleteCluster.
+message UndeleteClusterMetadata {
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 1;
+
+  // The time at which this operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 2;
+}
+
+// Metadata type for operations initiated by the V2 BigtableAdmin service.
+// More complete information for such operations is available via the V2 API.
+message V2OperationMetadata {
+
+}
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_instance_admin.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_instance_admin.proto
new file mode 100644
index 000000000000..ec992ea0f818
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_instance_admin.proto
@@ -0,0 +1,456 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.bigtable.admin.v2;
+
+import "google/api/annotations.proto";
+import "google/bigtable/admin/v2/instance.proto";
+import "google/iam/v1/iam_policy.proto";
+import "google/iam/v1/policy.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableInstanceAdminProto";
+option java_package = "com.google.bigtable.admin.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2";
+
+
+// Service for creating, configuring, and deleting Cloud Bigtable Instances and
+// Clusters. Provides access to the Instance and Cluster schemas only, not the
+// tables' metadata or data stored in those tables.
+service BigtableInstanceAdmin {
+  // Create an instance within a project.
+  rpc CreateInstance(CreateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*}/instances"
+      body: "*"
+    };
+  }
+
+  // Gets information about an instance.
+  rpc GetInstance(GetInstanceRequest) returns (Instance) {
+    option (google.api.http) = {
+      get: "/v2/{name=projects/*/instances/*}"
+    };
+  }
+
+  // Lists information about instances in a project.
+  rpc ListInstances(ListInstancesRequest) returns (ListInstancesResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*}/instances"
+    };
+  }
+
+  // Updates an instance within a project.
+  rpc UpdateInstance(Instance) returns (Instance) {
+    option (google.api.http) = {
+      put: "/v2/{name=projects/*/instances/*}"
+      body: "*"
+    };
+  }
+
+  // Partially updates an instance within a project.
+  rpc PartialUpdateInstance(PartialUpdateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v2/{instance.name=projects/*/instances/*}"
+      body: "instance"
+    };
+  }
+
+  // Delete an instance from a project.
+  rpc DeleteInstance(DeleteInstanceRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=projects/*/instances/*}"
+    };
+  }
+
+  // Creates a cluster within an instance.
+  rpc CreateCluster(CreateClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*/instances/*}/clusters"
+      body: "cluster"
+    };
+  }
+
+  // Gets information about a cluster.
+  rpc GetCluster(GetClusterRequest) returns (Cluster) {
+    option (google.api.http) = {
+      get: "/v2/{name=projects/*/instances/*/clusters/*}"
+    };
+  }
+
+  // Lists information about clusters in an instance.
+  rpc ListClusters(ListClustersRequest) returns (ListClustersResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*/instances/*}/clusters"
+    };
+  }
+
+  // Updates a cluster within an instance.
+  rpc UpdateCluster(Cluster) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      put: "/v2/{name=projects/*/instances/*/clusters/*}"
+      body: "*"
+    };
+  }
+
+  // Deletes a cluster from an instance.
+  rpc DeleteCluster(DeleteClusterRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=projects/*/instances/*/clusters/*}"
+    };
+  }
+
+  // Creates an app profile within an instance.
+  rpc CreateAppProfile(CreateAppProfileRequest) returns (AppProfile) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*/instances/*}/appProfiles"
+      body: "app_profile"
+    };
+  }
+
+  // Gets information about an app profile.
+  rpc GetAppProfile(GetAppProfileRequest) returns (AppProfile) {
+    option (google.api.http) = {
+      get: "/v2/{name=projects/*/instances/*/appProfiles/*}"
+    };
+  }
+
+  // Lists information about app profiles in an instance.
+  rpc ListAppProfiles(ListAppProfilesRequest) returns (ListAppProfilesResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*/instances/*}/appProfiles"
+    };
+  }
+
+  // Updates an app profile within an instance.
+  rpc UpdateAppProfile(UpdateAppProfileRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v2/{app_profile.name=projects/*/instances/*/appProfiles/*}"
+      body: "app_profile"
+    };
+  }
+
+  // Deletes an app profile from an instance.
+  rpc DeleteAppProfile(DeleteAppProfileRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=projects/*/instances/*/appProfiles/*}"
+    };
+  }
+
+  // Gets the access control policy for an instance resource. Returns an empty
+  // policy if an instance exists but does not have a policy set.
+  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v2/{resource=projects/*/instances/*}:getIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Sets the access control policy on an instance resource. Replaces any
+  // existing policy.
+  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v2/{resource=projects/*/instances/*}:setIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Returns permissions that the caller has on the specified instance resource.
+  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) {
+    option (google.api.http) = {
+      post: "/v2/{resource=projects/*/instances/*}:testIamPermissions"
+      body: "*"
+    };
+  }
+}
+
+// Request message for BigtableInstanceAdmin.CreateInstance.
+message CreateInstanceRequest {
+  // The unique name of the project in which to create the new instance.
+  // Values are of the form `projects/<project>`.
+  string parent = 1;
+
+  // The ID to be used when referring to the new instance within its project,
+  // e.g., just `myinstance` rather than
+  // `projects/myproject/instances/myinstance`.
+  string instance_id = 2;
+
+  // The instance to create.
+  // Fields marked `OutputOnly` must be left blank.
+  Instance instance = 3;
+
+  // The clusters to be created within the instance, mapped by desired
+  // cluster ID, e.g., just `mycluster` rather than
+  // `projects/myproject/instances/myinstance/clusters/mycluster`.
+  // Fields marked `OutputOnly` must be left blank.
+  // Currently, at most two clusters can be specified.
+  map<string, Cluster> clusters = 4;
+}
+
+// Request message for BigtableInstanceAdmin.GetInstance.
+message GetInstanceRequest {
+  // The unique name of the requested instance. Values are of the form
+  // `projects/<project>/instances/<instance>`.
+  string name = 1;
+}
+
+// Request message for BigtableInstanceAdmin.ListInstances.
+message ListInstancesRequest {
+  // The unique name of the project for which a list of instances is requested.
+  // Values are of the form `projects/<project>`.
+  string parent = 1;
+
+  // DEPRECATED: This field is unused and ignored.
+  string page_token = 2;
+}
+
+// Response message for BigtableInstanceAdmin.ListInstances.
+message ListInstancesResponse {
+  // The list of requested instances.
+  repeated Instance instances = 1;
+
+  // Locations from which Instance information could not be retrieved,
+  // due to an outage or some other transient condition.
+  // Instances whose Clusters are all in one of the failed locations
+  // may be missing from `instances`, and Instances with at least one
+  // Cluster in a failed location may only have partial information returned.
+  // Values are of the form `projects/<project>/locations/<zone_id>`
+  repeated string failed_locations = 2;
+
+  // DEPRECATED: This field is unused and ignored.
+  string next_page_token = 3;
+}
+
+// Request message for BigtableInstanceAdmin.PartialUpdateInstance.
+message PartialUpdateInstanceRequest {
+  // The Instance which will (partially) replace the current value.
+  Instance instance = 1;
+
+  // The subset of Instance fields which should be replaced.
+  // Must be explicitly set.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for BigtableInstanceAdmin.DeleteInstance.
+message DeleteInstanceRequest {
+  // The unique name of the instance to be deleted.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string name = 1;
+}
+
+// Request message for BigtableInstanceAdmin.CreateCluster.
+message CreateClusterRequest {
+  // The unique name of the instance in which to create the new cluster.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // The ID to be used when referring to the new cluster within its instance,
+  // e.g., just `mycluster` rather than
+  // `projects/myproject/instances/myinstance/clusters/mycluster`.
+  string cluster_id = 2;
+
+  // The cluster to be created.
+  // Fields marked `OutputOnly` must be left blank.
+  Cluster cluster = 3;
+}
+
+// Request message for BigtableInstanceAdmin.GetCluster.
+message GetClusterRequest {
+  // The unique name of the requested cluster. Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>`.
+  string name = 1;
+}
+
+// Request message for BigtableInstanceAdmin.ListClusters.
+message ListClustersRequest {
+  // The unique name of the instance for which a list of clusters is requested.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  // Use `<instance> = '-'` to list Clusters for all Instances in a project,
+  // e.g., `projects/myproject/instances/-`.
+  string parent = 1;
+
+  // DEPRECATED: This field is unused and ignored.
+  string page_token = 2;
+}
+
+// Response message for BigtableInstanceAdmin.ListClusters.
+message ListClustersResponse {
+  // The list of requested clusters.
+  repeated Cluster clusters = 1;
+
+  // Locations from which Cluster information could not be retrieved,
+  // due to an outage or some other transient condition.
+  // Clusters from these locations may be missing from `clusters`,
+  // or may only have partial information returned.
+  // Values are of the form `projects/<project>/locations/<zone_id>`
+  repeated string failed_locations = 2;
+
+  // DEPRECATED: This field is unused and ignored.
+  string next_page_token = 3;
+}
+
+// Request message for BigtableInstanceAdmin.DeleteCluster.
+message DeleteClusterRequest {
+  // The unique name of the cluster to be deleted. Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>`.
+  string name = 1;
+}
+
+// The metadata for the Operation returned by CreateInstance.
+message CreateInstanceMetadata {
+  // The request that prompted the initiation of this CreateInstance operation.
+  CreateInstanceRequest original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// The metadata for the Operation returned by UpdateInstance.
+message UpdateInstanceMetadata {
+  // The request that prompted the initiation of this UpdateInstance operation.
+  PartialUpdateInstanceRequest original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// The metadata for the Operation returned by CreateCluster.
+message CreateClusterMetadata {
+  // The request that prompted the initiation of this CreateCluster operation.
+  CreateClusterRequest original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// The metadata for the Operation returned by UpdateCluster.
+message UpdateClusterMetadata {
+  // The request that prompted the initiation of this UpdateCluster operation.
+  Cluster original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// Request message for BigtableInstanceAdmin.CreateAppProfile.
+message CreateAppProfileRequest {
+  // The unique name of the instance in which to create the new app profile.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // The ID to be used when referring to the new app profile within its
+  // instance, e.g., just `myprofile` rather than
+  // `projects/myproject/instances/myinstance/appProfiles/myprofile`.
+  string app_profile_id = 2;
+
+  // The app profile to be created.
+  // Fields marked `OutputOnly` will be ignored.
+  AppProfile app_profile = 3;
+
+  // If true, ignore safety checks when creating the app profile.
+  bool ignore_warnings = 4;
+}
+
+// Request message for BigtableInstanceAdmin.GetAppProfile.
+message GetAppProfileRequest {
+  // The unique name of the requested app profile. Values are of the form
+  // `projects/<project>/instances/<instance>/appProfiles/<app_profile>`.
+  string name = 1;
+}
+
+// Request message for BigtableInstanceAdmin.ListAppProfiles.
+message ListAppProfilesRequest {
+  // The unique name of the instance for which a list of app profiles is
+  // requested. Values are of the form
+  // `projects/<project>/instances/<instance>`.
+  // Use `<instance> = '-'` to list AppProfiles for all Instances in a project,
+  // e.g., `projects/myproject/instances/-`.
+  string parent = 1;
+
+  // Maximum number of results per page.
+  // CURRENTLY UNIMPLEMENTED AND IGNORED.
+  int32 page_size = 3;
+
+  // The value of `next_page_token` returned by a previous call.
+  string page_token = 2;
+}
+
+// Response message for BigtableInstanceAdmin.ListAppProfiles.
+message ListAppProfilesResponse {
+  // The list of requested app profiles.
+  repeated AppProfile app_profiles = 1;
+
+  // Set if not all app profiles could be returned in a single response.
+  // Pass this value to `page_token` in another request to get the next
+  // page of results.
+  string next_page_token = 2;
+
+  // Locations from which AppProfile information could not be retrieved,
+  // due to an outage or some other transient condition.
+  // AppProfiles from these locations may be missing from `app_profiles`.
+  // Values are of the form `projects/<project>/locations/<zone_id>`
+  repeated string failed_locations = 3;
+}
+
+// Request message for BigtableInstanceAdmin.UpdateAppProfile.
+message UpdateAppProfileRequest {
+  // The app profile which will (partially) replace the current value.
+  AppProfile app_profile = 1;
+
+  // The subset of app profile fields which should be replaced.
+  // If unset, all fields will be replaced.
+  google.protobuf.FieldMask update_mask = 2;
+
+  // If true, ignore safety checks when updating the app profile.
+  bool ignore_warnings = 3;
+}
+
+
+// Request message for BigtableInstanceAdmin.DeleteAppProfile.
+message DeleteAppProfileRequest {
+  // The unique name of the app profile to be deleted. Values are of the form
+  // `projects/<project>/instances/<instance>/appProfiles/<app_profile>`.
+  string name = 1;
+
+  // If true, ignore safety checks when deleting the app profile.
+  bool ignore_warnings = 2;
+}
+
+// The metadata for the Operation returned by UpdateAppProfile.
+message UpdateAppProfileMetadata {
+
+}
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_admin.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_admin.proto
new file mode 100644
index 000000000000..2d5bddf302aa
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_admin.proto
@@ -0,0 +1,525 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.bigtable.admin.v2;
+
+import "google/api/annotations.proto";
+import "google/bigtable/admin/v2/table.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableTableAdminProto";
+option java_package = "com.google.bigtable.admin.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2";
+
+
+// Service for creating, configuring, and deleting Cloud Bigtable tables.
+//
+//
+// Provides access to the table schemas only, not the data stored within
+// the tables.
+service BigtableTableAdmin {
+  // Creates a new table in the specified instance.
+  // The table can be created with a full set of initial column families,
+  // specified in the request.
+  rpc CreateTable(CreateTableRequest) returns (Table) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*/instances/*}/tables"
+      body: "*"
+    };
+  }
+
+  // Creates a new table from the specified snapshot. The target table must
+  // not exist. The snapshot and the table must be in the same instance.
+  //
+  // Note: This is a private alpha release of Cloud Bigtable snapshots. This
+  // feature is not currently available to most Cloud Bigtable customers. This
+  // feature might be changed in backward-incompatible ways and is not
+  // recommended for production use. It is not subject to any SLA or deprecation
+  // policy.
+  rpc CreateTableFromSnapshot(CreateTableFromSnapshotRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*/instances/*}/tables:createFromSnapshot"
+      body: "*"
+    };
+  }
+
+  // Lists all tables served from a specified instance.
+  rpc ListTables(ListTablesRequest) returns (ListTablesResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*/instances/*}/tables"
+    };
+  }
+
+  // Gets metadata information about the specified table.
+  rpc GetTable(GetTableRequest) returns (Table) {
+    option (google.api.http) = {
+      get: "/v2/{name=projects/*/instances/*/tables/*}"
+    };
+  }
+
+  // Permanently deletes a specified table and all of its data.
+  rpc DeleteTable(DeleteTableRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=projects/*/instances/*/tables/*}"
+    };
+  }
+
+  // Performs a series of column family modifications on the specified table.
+  // Either all or none of the modifications will occur before this method
+  // returns, but data requests received prior to that point may see a table
+  // where only some modifications have taken effect.
+  rpc ModifyColumnFamilies(ModifyColumnFamiliesRequest) returns (Table) {
+    option (google.api.http) = {
+      post: "/v2/{name=projects/*/instances/*/tables/*}:modifyColumnFamilies"
+      body: "*"
+    };
+  }
+
+  // Permanently drop/delete a row range from a specified table. The request can
+  // specify whether to delete all rows in a table, or only those that match a
+  // particular prefix.
+  rpc DropRowRange(DropRowRangeRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v2/{name=projects/*/instances/*/tables/*}:dropRowRange"
+      body: "*"
+    };
+  }
+
+  // Generates a consistency token for a Table, which can be used in
+  // CheckConsistency to check whether mutations to the table that finished
+  // before this call started have been replicated. The tokens will be available
+  // for 90 days.
+  rpc GenerateConsistencyToken(GenerateConsistencyTokenRequest) returns (GenerateConsistencyTokenResponse) {
+    option (google.api.http) = {
+      post: "/v2/{name=projects/*/instances/*/tables/*}:generateConsistencyToken"
+      body: "*"
+    };
+  }
+
+  // Checks replication consistency based on a consistency token, that is, if
+  // replication has caught up based on the conditions specified in the token
+  // and the check request.
+  rpc CheckConsistency(CheckConsistencyRequest) returns (CheckConsistencyResponse) {
+    option (google.api.http) = {
+      post: "/v2/{name=projects/*/instances/*/tables/*}:checkConsistency"
+      body: "*"
+    };
+  }
+
+  // Creates a new snapshot in the specified cluster from the specified
+  // source table. The cluster and the table must be in the same instance.
+  //
+  // Note: This is a private alpha release of Cloud Bigtable snapshots. This
+  // feature is not currently available to most Cloud Bigtable customers. This
+  // feature might be changed in backward-incompatible ways and is not
+  // recommended for production use. It is not subject to any SLA or deprecation
+  // policy.
+  rpc SnapshotTable(SnapshotTableRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v2/{name=projects/*/instances/*/tables/*}:snapshot"
+      body: "*"
+    };
+  }
+
+  // Gets metadata information about the specified snapshot.
+  //
+  // Note: This is a private alpha release of Cloud Bigtable snapshots. This
+  // feature is not currently available to most Cloud Bigtable customers. This
+  // feature might be changed in backward-incompatible ways and is not
+  // recommended for production use. It is not subject to any SLA or deprecation
+  // policy.
+  rpc GetSnapshot(GetSnapshotRequest) returns (Snapshot) {
+    option (google.api.http) = {
+      get: "/v2/{name=projects/*/instances/*/clusters/*/snapshots/*}"
+    };
+  }
+
+  // Lists all snapshots associated with the specified cluster.
+  //
+  // Note: This is a private alpha release of Cloud Bigtable snapshots. This
+  // feature is not currently available to most Cloud Bigtable customers. This
+  // feature might be changed in backward-incompatible ways and is not
+  // recommended for production use. It is not subject to any SLA or deprecation
+  // policy.
+  rpc ListSnapshots(ListSnapshotsRequest) returns (ListSnapshotsResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*/instances/*/clusters/*}/snapshots"
+    };
+  }
+
+  // Permanently deletes the specified snapshot.
+  //
+  // Note: This is a private alpha release of Cloud Bigtable snapshots. This
+  // feature is not currently available to most Cloud Bigtable customers. This
+  // feature might be changed in backward-incompatible ways and is not
+  // recommended for production use. It is not subject to any SLA or deprecation
+  // policy.
+  rpc DeleteSnapshot(DeleteSnapshotRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=projects/*/instances/*/clusters/*/snapshots/*}"
+    };
+  }
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.CreateTable][google.bigtable.admin.v2.BigtableTableAdmin.CreateTable]
+message CreateTableRequest {
+  // An initial split point for a newly created table.
+  message Split {
+    // Row key to use as an initial tablet boundary.
+    bytes key = 1;
+  }
+
+  // The unique name of the instance in which to create the table.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // The name by which the new table should be referred to within the parent
+  // instance, e.g., `foobar` rather than `<parent>/tables/foobar`.
+  string table_id = 2;
+
+  // The Table to create.
+  Table table = 3;
+
+  // The optional list of row keys that will be used to initially split the
+  // table into several tablets (tablets are similar to HBase regions).
+  // Given two split keys, `s1` and `s2`, three tablets will be created,
+  // spanning the key ranges: `[, s1), [s1, s2), [s2, )`.
+  //
+  // Example:
+  //
+  // * Row keys := `["a", "apple", "custom", "customer_1", "customer_2",`
+  //                `"other", "zz"]`
+  // * initial_split_keys := `["apple", "customer_1", "customer_2", "other"]`
+  // * Key assignment:
+  //     - Tablet 1 `[, apple)                => {"a"}.`
+  //     - Tablet 2 `[apple, customer_1)      => {"apple", "custom"}.`
+  //     - Tablet 3 `[customer_1, customer_2) => {"customer_1"}.`
+  //     - Tablet 4 `[customer_2, other)      => {"customer_2"}.`
+  //     - Tablet 5 `[other, )                => {"other", "zz"}.`
+  repeated Split initial_splits = 4;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message CreateTableFromSnapshotRequest {
+  // The unique name of the instance in which to create the table.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // The name by which the new table should be referred to within the parent
+  // instance, e.g., `foobar` rather than `<parent>/tables/foobar`.
+  string table_id = 2;
+
+  // The unique name of the snapshot from which to restore the table. The
+  // snapshot and the table must be in the same instance.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>/snapshots/<snapshot>`.
+  string source_snapshot = 3;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange][google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange]
+message DropRowRangeRequest {
+  // The unique name of the table on which to drop a range of rows.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+
+  // Delete all rows or by prefix.
+  oneof target {
+    // Delete all rows that start with this row key prefix. Prefix cannot be
+    // zero length.
+    bytes row_key_prefix = 2;
+
+    // Delete all rows in the table. Setting this to false is a no-op.
+    bool delete_all_data_from_table = 3;
+  }
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables]
+message ListTablesRequest {
+  // The unique name of the instance for which tables should be listed.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // The view to be applied to the returned tables' fields.
+  // Defaults to `NAME_ONLY` if unspecified; no others are currently supported.
+  Table.View view = 2;
+
+  // Maximum number of results per page.
+  // CURRENTLY UNIMPLEMENTED AND IGNORED.
+  int32 page_size = 4;
+
+  // The value of `next_page_token` returned by a previous call.
+  string page_token = 3;
+}
+
+// Response message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables]
+message ListTablesResponse {
+  // The tables present in the requested instance.
+  repeated Table tables = 1;
+
+  // Set if not all tables could be returned in a single response.
+  // Pass this value to `page_token` in another request to get the next
+  // page of results.
+  string next_page_token = 2;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.GetTable][google.bigtable.admin.v2.BigtableTableAdmin.GetTable]
+message GetTableRequest {
+  // The unique name of the requested table.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+
+  // The view to be applied to the returned table's fields.
+  // Defaults to `SCHEMA_VIEW` if unspecified.
+  Table.View view = 2;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable]
+message DeleteTableRequest {
+  // The unique name of the table to be deleted.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies][google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies]
+message ModifyColumnFamiliesRequest {
+  // A create, update, or delete of a particular column family.
+  message Modification {
+    // The ID of the column family to be modified.
+    string id = 1;
+
+    // Column familiy modifications.
+    oneof mod {
+      // Create a new column family with the specified schema, or fail if
+      // one already exists with the given ID.
+      ColumnFamily create = 2;
+
+      // Update an existing column family to the specified schema, or fail
+      // if no column family exists with the given ID.
+      ColumnFamily update = 3;
+
+      // Drop (delete) the column family with the given ID, or fail if no such
+      // family exists.
+      bool drop = 4;
+    }
+  }
+
+  // The unique name of the table whose families should be modified.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+
+  // Modifications to be atomically applied to the specified table's families.
+  // Entries are applied in order, meaning that earlier modifications can be
+  // masked by later ones (in the case of repeated updates to the same family,
+  // for example).
+  repeated Modification modifications = 2;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+message GenerateConsistencyTokenRequest {
+  // The unique name of the Table for which to create a consistency token.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+}
+
+// Response message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+message GenerateConsistencyTokenResponse {
+  // The generated consistency token.
+  string consistency_token = 1;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+message CheckConsistencyRequest {
+  // The unique name of the Table for which to check replication consistency.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+
+  // The token created using GenerateConsistencyToken for the Table.
+  string consistency_token = 2;
+}
+
+// Response message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+message CheckConsistencyResponse {
+  // True only if the token is consistent. A token is consistent if replication
+  // has caught up with the restrictions specified in the request.
+  bool consistent = 1;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable][google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message SnapshotTableRequest {
+  // The unique name of the table to have the snapshot taken.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+
+  // The name of the cluster where the snapshot will be created in.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>`.
+  string cluster = 2;
+
+  // The ID by which the new snapshot should be referred to within the parent
+  // cluster, e.g., `mysnapshot` of the form: `[_a-zA-Z0-9][-_.a-zA-Z0-9]*`
+  // rather than
+  // `projects/<project>/instances/<instance>/clusters/<cluster>/snapshots/mysnapshot`.
+  string snapshot_id = 3;
+
+  // The amount of time that the new snapshot can stay active after it is
+  // created. Once 'ttl' expires, the snapshot will get deleted. The maximum
+  // amount of time a snapshot can stay active is 7 days. If 'ttl' is not
+  // specified, the default value of 24 hours will be used.
+  google.protobuf.Duration ttl = 4;
+
+  // Description of the snapshot.
+  string description = 5;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message GetSnapshotRequest {
+  // The unique name of the requested snapshot.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>/snapshots/<snapshot>`.
+  string name = 1;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message ListSnapshotsRequest {
+  // The unique name of the cluster for which snapshots should be listed.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>`.
+  // Use `<cluster> = '-'` to list snapshots for all clusters in an instance,
+  // e.g., `projects/<project>/instances/<instance>/clusters/-`.
+  string parent = 1;
+
+  // The maximum number of snapshots to return per page.
+  // CURRENTLY UNIMPLEMENTED AND IGNORED.
+  int32 page_size = 2;
+
+  // The value of `next_page_token` returned by a previous call.
+  string page_token = 3;
+}
+
+// Response message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message ListSnapshotsResponse {
+  // The snapshots present in the requested cluster.
+  repeated Snapshot snapshots = 1;
+
+  // Set if not all snapshots could be returned in a single response.
+  // Pass this value to `page_token` in another request to get the next
+  // page of results.
+  string next_page_token = 2;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message DeleteSnapshotRequest {
+  // The unique name of the snapshot to be deleted.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>/snapshots/<snapshot>`.
+  string name = 1;
+}
+
+// The metadata for the Operation returned by SnapshotTable.
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message SnapshotTableMetadata {
+  // The request that prompted the initiation of this SnapshotTable operation.
+  SnapshotTableRequest original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// The metadata for the Operation returned by CreateTableFromSnapshot.
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message CreateTableFromSnapshotMetadata {
+  // The request that prompted the initiation of this CreateTableFromSnapshot
+  // operation.
+  CreateTableFromSnapshotRequest original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_data.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_data.proto
new file mode 100644
index 000000000000..e4efb74f560e
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_data.proto
@@ -0,0 +1,126 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.table.v1;
+
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/table/v1;table";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableTableDataProto";
+option java_package = "com.google.bigtable.admin.table.v1";
+
+
+// A collection of user data indexed by row, column, and timestamp.
+// Each table is served using the resources of its parent cluster.
+message Table {
+  enum TimestampGranularity {
+    MILLIS = 0;
+  }
+
+  // A unique identifier of the form
+  // <cluster_name>/tables/[_a-zA-Z0-9][-_.a-zA-Z0-9]*
+  string name = 1;
+
+  // If this Table is in the process of being created, the Operation used to
+  // track its progress. As long as this operation is present, the Table will
+  // not accept any Table Admin or Read/Write requests.
+  google.longrunning.Operation current_operation = 2;
+
+  // The column families configured for this table, mapped by column family id.
+  map<string, ColumnFamily> column_families = 3;
+
+  // The granularity (e.g. MILLIS, MICROS) at which timestamps are stored in
+  // this table. Timestamps not matching the granularity will be rejected.
+  // Cannot be changed once the table is created.
+  TimestampGranularity granularity = 4;
+}
+
+// A set of columns within a table which share a common configuration.
+message ColumnFamily {
+  // A unique identifier of the form <table_name>/columnFamilies/[-_.a-zA-Z0-9]+
+  // The last segment is the same as the "name" field in
+  // google.bigtable.v1.Family.
+  string name = 1;
+
+  // Garbage collection expression specified by the following grammar:
+  //   GC = EXPR
+  //      | "" ;
+  //   EXPR = EXPR, "||", EXPR              (* lowest precedence *)
+  //        | EXPR, "&&", EXPR
+  //        | "(", EXPR, ")"                (* highest precedence *)
+  //        | PROP ;
+  //   PROP = "version() >", NUM32
+  //        | "age() >", NUM64, [ UNIT ] ;
+  //   NUM32 = non-zero-digit { digit } ;    (* # NUM32 <= 2^32 - 1 *)
+  //   NUM64 = non-zero-digit { digit } ;    (* # NUM64 <= 2^63 - 1 *)
+  //   UNIT =  "d" | "h" | "m"  (* d=days, h=hours, m=minutes, else micros *)
+  // GC expressions can be up to 500 characters in length
+  //
+  // The different types of PROP are defined as follows:
+  //   version() - cell index, counting from most recent and starting at 1
+  //   age() - age of the cell (current time minus cell timestamp)
+  //
+  // Example: "version() > 3 || (age() > 3d && version() > 1)"
+  //   drop cells beyond the most recent three, and drop cells older than three
+  //   days unless they're the most recent cell in the row/column
+  //
+  // Garbage collection executes opportunistically in the background, and so
+  // it's possible for reads to return a cell even if it matches the active GC
+  // expression for its family.
+  string gc_expression = 2;
+
+  // Garbage collection rule specified as a protobuf.
+  // Supersedes `gc_expression`.
+  // Must serialize to at most 500 bytes.
+  //
+  // NOTE: Garbage collection executes opportunistically in the background, and
+  // so it's possible for reads to return a cell even if it matches the active
+  // GC expression for its family.
+  GcRule gc_rule = 3;
+}
+
+// Rule for determining which cells to delete during garbage collection.
+message GcRule {
+  // A GcRule which deletes cells matching all of the given rules.
+  message Intersection {
+    // Only delete cells which would be deleted by every element of `rules`.
+    repeated GcRule rules = 1;
+  }
+
+  // A GcRule which deletes cells matching any of the given rules.
+  message Union {
+    // Delete cells which would be deleted by any element of `rules`.
+    repeated GcRule rules = 1;
+  }
+
+  oneof rule {
+    // Delete all cells in a column except the most recent N.
+    int32 max_num_versions = 1;
+
+    // Delete cells in a column older than the given age.
+    // Values must be at least one millisecond, and will be truncated to
+    // microsecond granularity.
+    google.protobuf.Duration max_age = 2;
+
+    // Delete cells that would be deleted by every nested rule.
+    Intersection intersection = 3;
+
+    // Delete cells that would be deleted by any nested rule.
+    Union union = 4;
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_service.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_service.proto
new file mode 100644
index 000000000000..6e968fee17c1
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_service.proto
@@ -0,0 +1,80 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.table.v1;
+
+import "google/api/annotations.proto";
+import "google/bigtable/admin/table/v1/bigtable_table_data.proto";
+import "google/bigtable/admin/table/v1/bigtable_table_service_messages.proto";
+import "google/protobuf/empty.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/table/v1;table";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableTableServicesProto";
+option java_package = "com.google.bigtable.admin.table.v1";
+
+
+// Service for creating, configuring, and deleting Cloud Bigtable tables.
+// Provides access to the table schemas only, not the data stored within the tables.
+service BigtableTableService {
+  // Creates a new table, to be served from a specified cluster.
+  // The table can be created with a full set of initial column families,
+  // specified in the request.
+  rpc CreateTable(CreateTableRequest) returns (Table) {
+    option (google.api.http) = { post: "/v1/{name=projects/*/zones/*/clusters/*}/tables" body: "*" };
+  }
+
+  // Lists the names of all tables served from a specified cluster.
+  rpc ListTables(ListTablesRequest) returns (ListTablesResponse) {
+    option (google.api.http) = { get: "/v1/{name=projects/*/zones/*/clusters/*}/tables" };
+  }
+
+  // Gets the schema of the specified table, including its column families.
+  rpc GetTable(GetTableRequest) returns (Table) {
+    option (google.api.http) = { get: "/v1/{name=projects/*/zones/*/clusters/*/tables/*}" };
+  }
+
+  // Permanently deletes a specified table and all of its data.
+  rpc DeleteTable(DeleteTableRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { delete: "/v1/{name=projects/*/zones/*/clusters/*/tables/*}" };
+  }
+
+  // Changes the name of a specified table.
+  // Cannot be used to move tables between clusters, zones, or projects.
+  rpc RenameTable(RenameTableRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { post: "/v1/{name=projects/*/zones/*/clusters/*/tables/*}:rename" body: "*" };
+  }
+
+  // Creates a new column family within a specified table.
+  rpc CreateColumnFamily(CreateColumnFamilyRequest) returns (ColumnFamily) {
+    option (google.api.http) = { post: "/v1/{name=projects/*/zones/*/clusters/*/tables/*}/columnFamilies" body: "*" };
+  }
+
+  // Changes the configuration of a specified column family.
+  rpc UpdateColumnFamily(ColumnFamily) returns (ColumnFamily) {
+    option (google.api.http) = { put: "/v1/{name=projects/*/zones/*/clusters/*/tables/*/columnFamilies/*}" body: "*" };
+  }
+
+  // Permanently deletes a specified column family and all of its data.
+  rpc DeleteColumnFamily(DeleteColumnFamilyRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { delete: "/v1/{name=projects/*/zones/*/clusters/*/tables/*/columnFamilies/*}" };
+  }
+
+  // Delete all rows in a table corresponding to a particular prefix
+  rpc BulkDeleteRows(BulkDeleteRowsRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { post: "/v1/{table_name=projects/*/zones/*/clusters/*/tables/*}:bulkDeleteRows" body: "*" };
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_service_messages.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_service_messages.proto
new file mode 100644
index 000000000000..617ede65592f
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/bigtable_table_service_messages.proto
@@ -0,0 +1,116 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.table.v1;
+
+import "google/bigtable/admin/table/v1/bigtable_table_data.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/table/v1;table";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableTableServiceMessagesProto";
+option java_package = "com.google.bigtable.admin.table.v1";
+
+
+message CreateTableRequest {
+  // The unique name of the cluster in which to create the new table.
+  string name = 1;
+
+  // The name by which the new table should be referred to within the cluster,
+  // e.g. "foobar" rather than "<cluster_name>/tables/foobar".
+  string table_id = 2;
+
+  // The Table to create. The `name` field of the Table and all of its
+  // ColumnFamilies must be left blank, and will be populated in the response.
+  Table table = 3;
+
+  // The optional list of row keys that will be used to initially split the
+  // table into several tablets (Tablets are similar to HBase regions).
+  // Given two split keys, "s1" and "s2", three tablets will be created,
+  // spanning the key ranges: [, s1), [s1, s2), [s2, ).
+  //
+  // Example:
+  //  * Row keys := ["a", "apple", "custom", "customer_1", "customer_2",
+  //                 "other", "zz"]
+  //  * initial_split_keys := ["apple", "customer_1", "customer_2", "other"]
+  //  * Key assignment:
+  //    - Tablet 1 [, apple)                => {"a"}.
+  //    - Tablet 2 [apple, customer_1)      => {"apple", "custom"}.
+  //    - Tablet 3 [customer_1, customer_2) => {"customer_1"}.
+  //    - Tablet 4 [customer_2, other)      => {"customer_2"}.
+  //    - Tablet 5 [other, )                => {"other", "zz"}.
+  repeated string initial_split_keys = 4;
+}
+
+message ListTablesRequest {
+  // The unique name of the cluster for which tables should be listed.
+  string name = 1;
+}
+
+message ListTablesResponse {
+  // The tables present in the requested cluster.
+  // At present, only the names of the tables are populated.
+  repeated Table tables = 1;
+}
+
+message GetTableRequest {
+  // The unique name of the requested table.
+  string name = 1;
+}
+
+message DeleteTableRequest {
+  // The unique name of the table to be deleted.
+  string name = 1;
+}
+
+message RenameTableRequest {
+  // The current unique name of the table.
+  string name = 1;
+
+  // The new name by which the table should be referred to within its containing
+  // cluster, e.g. "foobar" rather than "<cluster_name>/tables/foobar".
+  string new_id = 2;
+}
+
+message CreateColumnFamilyRequest {
+  // The unique name of the table in which to create the new column family.
+  string name = 1;
+
+  // The name by which the new column family should be referred to within the
+  // table, e.g. "foobar" rather than "<table_name>/columnFamilies/foobar".
+  string column_family_id = 2;
+
+  // The column family to create. The `name` field must be left blank.
+  ColumnFamily column_family = 3;
+}
+
+message DeleteColumnFamilyRequest {
+  // The unique name of the column family to be deleted.
+  string name = 1;
+}
+
+message BulkDeleteRowsRequest {
+  // The unique name of the table on which to perform the bulk delete
+  string table_name = 1;
+
+  oneof target {
+    // Delete all rows that start with this row key prefix. Prefix cannot be
+    // zero length.
+    bytes row_key_prefix = 2;
+
+    // Delete all rows in the table. Setting this to false is a no-op.
+    bool delete_all_data_from_table = 3;
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/common.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/common.proto
new file mode 100644
index 000000000000..0ece12780eb9
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/common.proto
@@ -0,0 +1,41 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.bigtable.admin.v2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "CommonProto";
+option java_package = "com.google.bigtable.admin.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2";
+
+
+// Storage media types for persisting Bigtable data.
+enum StorageType {
+  // The user did not specify a storage type.
+  STORAGE_TYPE_UNSPECIFIED = 0;
+
+  // Flash (SSD) storage should be used.
+  SSD = 1;
+
+  // Magnetic drive (HDD) storage should be used.
+  HDD = 2;
+}
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/instance.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/instance.proto
new file mode 100644
index 000000000000..bb69b1f66d42
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/instance.proto
@@ -0,0 +1,208 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.bigtable.admin.v2;
+
+import "google/api/annotations.proto";
+import "google/bigtable/admin/v2/common.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "InstanceProto";
+option java_package = "com.google.bigtable.admin.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2";
+
+
+// A collection of Bigtable [Tables][google.bigtable.admin.v2.Table] and
+// the resources that serve them.
+// All tables in an instance are served from a single
+// [Cluster][google.bigtable.admin.v2.Cluster].
+message Instance {
+  // Possible states of an instance.
+  enum State {
+    // The state of the instance could not be determined.
+    STATE_NOT_KNOWN = 0;
+
+    // The instance has been successfully created and can serve requests
+    // to its tables.
+    READY = 1;
+
+    // The instance is currently being created, and may be destroyed
+    // if the creation process encounters an error.
+    CREATING = 2;
+  }
+
+  // The type of the instance.
+  enum Type {
+    // The type of the instance is unspecified. If set when creating an
+    // instance, a `PRODUCTION` instance will be created. If set when updating
+    // an instance, the type will be left unchanged.
+    TYPE_UNSPECIFIED = 0;
+
+    // An instance meant for production use. `serve_nodes` must be set
+    // on the cluster.
+    PRODUCTION = 1;
+
+    // The instance is meant for development and testing purposes only; it has
+    // no performance or uptime guarantees and is not covered by SLA.
+    // After a development instance is created, it can be upgraded by
+    // updating the instance to type `PRODUCTION`. An instance created
+    // as a production instance cannot be changed to a development instance.
+    // When creating a development instance, `serve_nodes` on the cluster must
+    // not be set.
+    DEVELOPMENT = 2;
+  }
+
+  // (`OutputOnly`)
+  // The unique name of the instance. Values are of the form
+  // `projects/<project>/instances/[a-z][a-z0-9\\-]+[a-z0-9]`.
+  string name = 1;
+
+  // The descriptive name for this instance as it appears in UIs.
+  // Can be changed at any time, but should be kept globally unique
+  // to avoid confusion.
+  string display_name = 2;
+
+  // (`OutputOnly`)
+  // The current state of the instance.
+  State state = 3;
+
+  // The type of the instance. Defaults to `PRODUCTION`.
+  Type type = 4;
+
+  // Labels are a flexible and lightweight mechanism for organizing cloud
+  // resources into groups that reflect a customer's organizational needs and
+  // deployment strategies. They can be used to filter resources and aggregate
+  // metrics.
+  //
+  // * Label keys must be between 1 and 63 characters long and must conform to
+  //   the regular expression: `[\p{Ll}\p{Lo}][\p{Ll}\p{Lo}\p{N}_-]{0,62}`.
+  // * Label values must be between 0 and 63 characters long and must conform to
+  //   the regular expression: `[\p{Ll}\p{Lo}\p{N}_-]{0,63}`.
+  // * No more than 64 labels can be associated with a given resource.
+  // * Keys and values must both be under 128 bytes.
+  map<string, string> labels = 5;
+}
+
+// A resizable group of nodes in a particular cloud location, capable
+// of serving all [Tables][google.bigtable.admin.v2.Table] in the parent
+// [Instance][google.bigtable.admin.v2.Instance].
+message Cluster {
+  // Possible states of a cluster.
+  enum State {
+    // The state of the cluster could not be determined.
+    STATE_NOT_KNOWN = 0;
+
+    // The cluster has been successfully created and is ready to serve requests.
+    READY = 1;
+
+    // The cluster is currently being created, and may be destroyed
+    // if the creation process encounters an error.
+    // A cluster may not be able to serve requests while being created.
+    CREATING = 2;
+
+    // The cluster is currently being resized, and may revert to its previous
+    // node count if the process encounters an error.
+    // A cluster is still capable of serving requests while being resized,
+    // but may exhibit performance as if its number of allocated nodes is
+    // between the starting and requested states.
+    RESIZING = 3;
+
+    // The cluster has no backing nodes. The data (tables) still
+    // exist, but no operations can be performed on the cluster.
+    DISABLED = 4;
+  }
+
+  // (`OutputOnly`)
+  // The unique name of the cluster. Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/[a-z][-a-z0-9]*`.
+  string name = 1;
+
+  // (`CreationOnly`)
+  // The location where this cluster's nodes and storage reside. For best
+  // performance, clients should be located as close as possible to this
+  // cluster. Currently only zones are supported, so values should be of the
+  // form `projects/<project>/locations/<zone>`.
+  string location = 2;
+
+  // (`OutputOnly`)
+  // The current state of the cluster.
+  State state = 3;
+
+  // The number of nodes allocated to this cluster. More nodes enable higher
+  // throughput and more consistent performance.
+  int32 serve_nodes = 4;
+
+  // (`CreationOnly`)
+  // The type of storage used by this cluster to serve its
+  // parent instance's tables, unless explicitly overridden.
+  StorageType default_storage_type = 5;
+}
+
+// A configuration object describing how Cloud Bigtable should treat traffic
+// from a particular end user application.
+message AppProfile {
+  // Read/write requests may be routed to any cluster in the instance, and will
+  // fail over to another cluster in the event of transient errors or delays.
+  // Choosing this option sacrifices read-your-writes consistency to improve
+  // availability.
+  message MultiClusterRoutingUseAny {
+
+  }
+
+  // Unconditionally routes all read/write requests to a specific cluster.
+  // This option preserves read-your-writes consistency, but does not improve
+  // availability.
+  message SingleClusterRouting {
+    // The cluster to which read/write requests should be routed.
+    string cluster_id = 1;
+
+    // Whether or not `CheckAndMutateRow` and `ReadModifyWriteRow` requests are
+    // allowed by this app profile. It is unsafe to send these requests to
+    // the same table/row/column in multiple clusters.
+    bool allow_transactional_writes = 2;
+  }
+
+  // (`OutputOnly`)
+  // The unique name of the app profile. Values are of the form
+  // `projects/<project>/instances/<instance>/appProfiles/[_a-zA-Z0-9][-_.a-zA-Z0-9]*`.
+  string name = 1;
+
+  // Strongly validated etag for optimistic concurrency control. Preserve the
+  // value returned from `GetAppProfile` when calling `UpdateAppProfile` to
+  // fail the request if there has been a modification in the mean time. The
+  // `update_mask` of the request need not include `etag` for this protection
+  // to apply.
+  // See [Wikipedia](https://en.wikipedia.org/wiki/HTTP_ETag) and
+  // [RFC 7232](https://tools.ietf.org/html/rfc7232#section-2.3) for more
+  // details.
+  string etag = 2;
+
+  // Optional long form description of the use case for this AppProfile.
+  string description = 3;
+
+  // The routing policy for all read/write requests which use this app profile.
+  // A value must be explicitly set.
+  oneof routing_policy {
+    // Use a multi-cluster routing policy that may pick any cluster.
+    MultiClusterRoutingUseAny multi_cluster_routing_use_any = 5;
+
+    // Use a single-cluster routing policy.
+    SingleClusterRouting single_cluster_routing = 6;
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_admin_v2/proto/table.proto b/bigtable/google/cloud/bigtable_admin_v2/proto/table.proto
new file mode 100644
index 000000000000..5d4374effc59
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_admin_v2/proto/table.proto
@@ -0,0 +1,221 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.bigtable.admin.v2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "TableProto";
+option java_package = "com.google.bigtable.admin.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2";
+
+
+// A collection of user data indexed by row, column, and timestamp.
+// Each table is served using the resources of its parent cluster.
+message Table {
+  // The state of a table's data in a particular cluster.
+  message ClusterState {
+    // Table replication states.
+    enum ReplicationState {
+      // The replication state of the table is unknown in this cluster.
+      STATE_NOT_KNOWN = 0;
+
+      // The cluster was recently created, and the table must finish copying
+      // over pre-existing data from other clusters before it can begin
+      // receiving live replication updates and serving Data API requests.
+      INITIALIZING = 1;
+
+      // The table is temporarily unable to serve Data API requests from this
+      // cluster due to planned internal maintenance.
+      PLANNED_MAINTENANCE = 2;
+
+      // The table is temporarily unable to serve Data API requests from this
+      // cluster due to unplanned or emergency maintenance.
+      UNPLANNED_MAINTENANCE = 3;
+
+      // The table can serve Data API requests from this cluster. Depending on
+      // replication delay, reads may not immediately reflect the state of the
+      // table in other clusters.
+      READY = 4;
+    }
+
+    // (`OutputOnly`)
+    // The state of replication for the table in this cluster.
+    ReplicationState replication_state = 1;
+  }
+
+  // Possible timestamp granularities to use when keeping multiple versions
+  // of data in a table.
+  enum TimestampGranularity {
+    // The user did not specify a granularity. Should not be returned.
+    // When specified during table creation, MILLIS will be used.
+    TIMESTAMP_GRANULARITY_UNSPECIFIED = 0;
+
+    // The table keeps data versioned at a granularity of 1ms.
+    MILLIS = 1;
+  }
+
+  // Defines a view over a table's fields.
+  enum View {
+    // Uses the default view for each method as documented in its request.
+    VIEW_UNSPECIFIED = 0;
+
+    // Only populates `name`.
+    NAME_ONLY = 1;
+
+    // Only populates `name` and fields related to the table's schema.
+    SCHEMA_VIEW = 2;
+
+    // Only populates `name` and fields related to the table's
+    // replication state.
+    REPLICATION_VIEW = 3;
+
+    // Populates all fields.
+    FULL = 4;
+  }
+
+  // (`OutputOnly`)
+  // The unique name of the table. Values are of the form
+  // `projects/<project>/instances/<instance>/tables/[_a-zA-Z0-9][-_.a-zA-Z0-9]*`.
+  // Views: `NAME_ONLY`, `SCHEMA_VIEW`, `REPLICATION_VIEW`, `FULL`
+  string name = 1;
+
+  // (`OutputOnly`)
+  // Map from cluster ID to per-cluster table state.
+  // If it could not be determined whether or not the table has data in a
+  // particular cluster (for example, if its zone is unavailable), then
+  // there will be an entry for the cluster with UNKNOWN `replication_status`.
+  // Views: `REPLICATION_VIEW`, `FULL`
+  map<string, ClusterState> cluster_states = 2;
+
+  // (`CreationOnly`)
+  // The column families configured for this table, mapped by column family ID.
+  // Views: `SCHEMA_VIEW`, `FULL`
+  map<string, ColumnFamily> column_families = 3;
+
+  // (`CreationOnly`)
+  // The granularity (i.e. `MILLIS`) at which timestamps are stored in
+  // this table. Timestamps not matching the granularity will be rejected.
+  // If unspecified at creation time, the value will be set to `MILLIS`.
+  // Views: `SCHEMA_VIEW`, `FULL`
+  TimestampGranularity granularity = 4;
+}
+
+// A set of columns within a table which share a common configuration.
+message ColumnFamily {
+  // Garbage collection rule specified as a protobuf.
+  // Must serialize to at most 500 bytes.
+  //
+  // NOTE: Garbage collection executes opportunistically in the background, and
+  // so it's possible for reads to return a cell even if it matches the active
+  // GC expression for its family.
+  GcRule gc_rule = 1;
+}
+
+// Rule for determining which cells to delete during garbage collection.
+message GcRule {
+  // A GcRule which deletes cells matching all of the given rules.
+  message Intersection {
+    // Only delete cells which would be deleted by every element of `rules`.
+    repeated GcRule rules = 1;
+  }
+
+  // A GcRule which deletes cells matching any of the given rules.
+  message Union {
+    // Delete cells which would be deleted by any element of `rules`.
+    repeated GcRule rules = 1;
+  }
+
+  // Garbage collection rules.
+  oneof rule {
+    // Delete all cells in a column except the most recent N.
+    int32 max_num_versions = 1;
+
+    // Delete cells in a column older than the given age.
+    // Values must be at least one millisecond, and will be truncated to
+    // microsecond granularity.
+    google.protobuf.Duration max_age = 2;
+
+    // Delete cells that would be deleted by every nested rule.
+    Intersection intersection = 3;
+
+    // Delete cells that would be deleted by any nested rule.
+    Union union = 4;
+  }
+}
+
+// A snapshot of a table at a particular time. A snapshot can be used as a
+// checkpoint for data restoration or a data source for a new table.
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message Snapshot {
+  // Possible states of a snapshot.
+  enum State {
+    // The state of the snapshot could not be determined.
+    STATE_NOT_KNOWN = 0;
+
+    // The snapshot has been successfully created and can serve all requests.
+    READY = 1;
+
+    // The snapshot is currently being created, and may be destroyed if the
+    // creation process encounters an error. A snapshot may not be restored to a
+    // table while it is being created.
+    CREATING = 2;
+  }
+
+  // (`OutputOnly`)
+  // The unique name of the snapshot.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>/snapshots/<snapshot>`.
+  string name = 1;
+
+  // (`OutputOnly`)
+  // The source table at the time the snapshot was taken.
+  Table source_table = 2;
+
+  // (`OutputOnly`)
+  // The size of the data in the source table at the time the snapshot was
+  // taken. In some cases, this value may be computed asynchronously via a
+  // background process and a placeholder of 0 will be used in the meantime.
+  int64 data_size_bytes = 3;
+
+  // (`OutputOnly`)
+  // The time when the snapshot is created.
+  google.protobuf.Timestamp create_time = 4;
+
+  // (`OutputOnly`)
+  // The time when the snapshot will be deleted. The maximum amount of time a
+  // snapshot can stay active is 365 days. If 'ttl' is not specified,
+  // the default maximum of 365 days will be used.
+  google.protobuf.Timestamp delete_time = 5;
+
+  // (`OutputOnly`)
+  // The current state of the snapshot.
+  State state = 6;
+
+  // (`OutputOnly`)
+  // Description of the snapshot.
+  string description = 7;
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable.proto
new file mode 100644
index 000000000000..d800c2c97ab8
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable.proto
@@ -0,0 +1,365 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.v2;
+
+import "google/api/annotations.proto";
+import "google/bigtable/v2/data.proto";
+import "google/protobuf/wrappers.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/v2;bigtable";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableProto";
+option java_package = "com.google.bigtable.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\V2";
+
+
+// Service for reading from and writing to existing Bigtable tables.
+service Bigtable {
+  // Streams back the contents of all requested rows in key order, optionally
+  // applying the same Reader filter to each. Depending on their size,
+  // rows and cells may be broken up across multiple responses, but
+  // atomicity of each row will still be preserved. See the
+  // ReadRowsResponse documentation for details.
+  rpc ReadRows(ReadRowsRequest) returns (stream ReadRowsResponse) {
+    option (google.api.http) = {
+      post: "/v2/{table_name=projects/*/instances/*/tables/*}:readRows"
+      body: "*"
+    };
+  }
+
+  // Returns a sample of row keys in the table. The returned row keys will
+  // delimit contiguous sections of the table of approximately equal size,
+  // which can be used to break up the data for distributed tasks like
+  // mapreduces.
+  rpc SampleRowKeys(SampleRowKeysRequest) returns (stream SampleRowKeysResponse) {
+    option (google.api.http) = {
+      get: "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys"
+    };
+  }
+
+  // Mutates a row atomically. Cells already present in the row are left
+  // unchanged unless explicitly changed by `mutation`.
+  rpc MutateRow(MutateRowRequest) returns (MutateRowResponse) {
+    option (google.api.http) = {
+      post: "/v2/{table_name=projects/*/instances/*/tables/*}:mutateRow"
+      body: "*"
+    };
+  }
+
+  // Mutates multiple rows in a batch. Each individual row is mutated
+  // atomically as in MutateRow, but the entire batch is not executed
+  // atomically.
+  rpc MutateRows(MutateRowsRequest) returns (stream MutateRowsResponse) {
+    option (google.api.http) = {
+      post: "/v2/{table_name=projects/*/instances/*/tables/*}:mutateRows"
+      body: "*"
+    };
+  }
+
+  // Mutates a row atomically based on the output of a predicate Reader filter.
+  rpc CheckAndMutateRow(CheckAndMutateRowRequest) returns (CheckAndMutateRowResponse) {
+    option (google.api.http) = {
+      post: "/v2/{table_name=projects/*/instances/*/tables/*}:checkAndMutateRow"
+      body: "*"
+    };
+  }
+
+  // Modifies a row atomically on the server. The method reads the latest
+  // existing timestamp and value from the specified columns and writes a new
+  // entry based on pre-defined read/modify/write rules. The new value for the
+  // timestamp is the greater of the existing timestamp or the current server
+  // time. The method returns the new contents of all modified cells.
+  rpc ReadModifyWriteRow(ReadModifyWriteRowRequest) returns (ReadModifyWriteRowResponse) {
+    option (google.api.http) = {
+      post: "/v2/{table_name=projects/*/instances/*/tables/*}:readModifyWriteRow"
+      body: "*"
+    };
+  }
+}
+
+// Request message for Bigtable.ReadRows.
+message ReadRowsRequest {
+  // The unique name of the table from which to read.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string table_name = 1;
+
+  // This value specifies routing for replication. If not specified, the
+  // "default" application profile will be used.
+  string app_profile_id = 5;
+
+  // The row keys and/or ranges to read. If not specified, reads from all rows.
+  RowSet rows = 2;
+
+  // The filter to apply to the contents of the specified row(s). If unset,
+  // reads the entirety of each row.
+  RowFilter filter = 3;
+
+  // The read will terminate after committing to N rows' worth of results. The
+  // default (zero) is to return all results.
+  int64 rows_limit = 4;
+}
+
+// Response message for Bigtable.ReadRows.
+message ReadRowsResponse {
+  // Specifies a piece of a row's contents returned as part of the read
+  // response stream.
+  message CellChunk {
+    // The row key for this chunk of data.  If the row key is empty,
+    // this CellChunk is a continuation of the same row as the previous
+    // CellChunk in the response stream, even if that CellChunk was in a
+    // previous ReadRowsResponse message.
+    bytes row_key = 1;
+
+    // The column family name for this chunk of data.  If this message
+    // is not present this CellChunk is a continuation of the same column
+    // family as the previous CellChunk.  The empty string can occur as a
+    // column family name in a response so clients must check
+    // explicitly for the presence of this message, not just for
+    // `family_name.value` being non-empty.
+    google.protobuf.StringValue family_name = 2;
+
+    // The column qualifier for this chunk of data.  If this message
+    // is not present, this CellChunk is a continuation of the same column
+    // as the previous CellChunk.  Column qualifiers may be empty so
+    // clients must check for the presence of this message, not just
+    // for `qualifier.value` being non-empty.
+    google.protobuf.BytesValue qualifier = 3;
+
+    // The cell's stored timestamp, which also uniquely identifies it
+    // within its column.  Values are always expressed in
+    // microseconds, but individual tables may set a coarser
+    // granularity to further restrict the allowed values. For
+    // example, a table which specifies millisecond granularity will
+    // only allow values of `timestamp_micros` which are multiples of
+    // 1000.  Timestamps are only set in the first CellChunk per cell
+    // (for cells split into multiple chunks).
+    int64 timestamp_micros = 4;
+
+    // Labels applied to the cell by a
+    // [RowFilter][google.bigtable.v2.RowFilter].  Labels are only set
+    // on the first CellChunk per cell.
+    repeated string labels = 5;
+
+    // The value stored in the cell.  Cell values can be split across
+    // multiple CellChunks.  In that case only the value field will be
+    // set in CellChunks after the first: the timestamp and labels
+    // will only be present in the first CellChunk, even if the first
+    // CellChunk came in a previous ReadRowsResponse.
+    bytes value = 6;
+
+    // If this CellChunk is part of a chunked cell value and this is
+    // not the final chunk of that cell, value_size will be set to the
+    // total length of the cell value.  The client can use this size
+    // to pre-allocate memory to hold the full cell value.
+    int32 value_size = 7;
+
+    oneof row_status {
+      // Indicates that the client should drop all previous chunks for
+      // `row_key`, as it will be re-read from the beginning.
+      bool reset_row = 8;
+
+      // Indicates that the client can safely process all previous chunks for
+      // `row_key`, as its data has been fully read.
+      bool commit_row = 9;
+    }
+  }
+
+  repeated CellChunk chunks = 1;
+
+  // Optionally the server might return the row key of the last row it
+  // has scanned.  The client can use this to construct a more
+  // efficient retry request if needed: any row keys or portions of
+  // ranges less than this row key can be dropped from the request.
+  // This is primarily useful for cases where the server has read a
+  // lot of data that was filtered out since the last committed row
+  // key, allowing the client to skip that work on a retry.
+  bytes last_scanned_row_key = 2;
+}
+
+// Request message for Bigtable.SampleRowKeys.
+message SampleRowKeysRequest {
+  // The unique name of the table from which to sample row keys.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string table_name = 1;
+
+  // This value specifies routing for replication. If not specified, the
+  // "default" application profile will be used.
+  string app_profile_id = 2;
+}
+
+// Response message for Bigtable.SampleRowKeys.
+message SampleRowKeysResponse {
+  // Sorted streamed sequence of sample row keys in the table. The table might
+  // have contents before the first row key in the list and after the last one,
+  // but a key containing the empty string indicates "end of table" and will be
+  // the last response given, if present.
+  // Note that row keys in this list may not have ever been written to or read
+  // from, and users should therefore not make any assumptions about the row key
+  // structure that are specific to their use case.
+  bytes row_key = 1;
+
+  // Approximate total storage space used by all rows in the table which precede
+  // `row_key`. Buffering the contents of all rows between two subsequent
+  // samples would require space roughly equal to the difference in their
+  // `offset_bytes` fields.
+  int64 offset_bytes = 2;
+}
+
+// Request message for Bigtable.MutateRow.
+message MutateRowRequest {
+  // The unique name of the table to which the mutation should be applied.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string table_name = 1;
+
+  // This value specifies routing for replication. If not specified, the
+  // "default" application profile will be used.
+  string app_profile_id = 4;
+
+  // The key of the row to which the mutation should be applied.
+  bytes row_key = 2;
+
+  // Changes to be atomically applied to the specified row. Entries are applied
+  // in order, meaning that earlier mutations can be masked by later ones.
+  // Must contain at least one entry and at most 100000.
+  repeated Mutation mutations = 3;
+}
+
+// Response message for Bigtable.MutateRow.
+message MutateRowResponse {
+
+}
+
+// Request message for BigtableService.MutateRows.
+message MutateRowsRequest {
+  message Entry {
+    // The key of the row to which the `mutations` should be applied.
+    bytes row_key = 1;
+
+    // Changes to be atomically applied to the specified row. Mutations are
+    // applied in order, meaning that earlier mutations can be masked by
+    // later ones.
+    // You must specify at least one mutation.
+    repeated Mutation mutations = 2;
+  }
+
+  // The unique name of the table to which the mutations should be applied.
+  string table_name = 1;
+
+  // This value specifies routing for replication. If not specified, the
+  // "default" application profile will be used.
+  string app_profile_id = 3;
+
+  // The row keys and corresponding mutations to be applied in bulk.
+  // Each entry is applied as an atomic mutation, but the entries may be
+  // applied in arbitrary order (even between entries for the same row).
+  // At least one entry must be specified, and in total the entries can
+  // contain at most 100000 mutations.
+  repeated Entry entries = 2;
+}
+
+// Response message for BigtableService.MutateRows.
+message MutateRowsResponse {
+  message Entry {
+    // The index into the original request's `entries` list of the Entry
+    // for which a result is being reported.
+    int64 index = 1;
+
+    // The result of the request Entry identified by `index`.
+    // Depending on how requests are batched during execution, it is possible
+    // for one Entry to fail due to an error with another Entry. In the event
+    // that this occurs, the same error will be reported for both entries.
+    google.rpc.Status status = 2;
+  }
+
+  // One or more results for Entries from the batch request.
+  repeated Entry entries = 1;
+}
+
+// Request message for Bigtable.CheckAndMutateRow.
+message CheckAndMutateRowRequest {
+  // The unique name of the table to which the conditional mutation should be
+  // applied.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string table_name = 1;
+
+  // This value specifies routing for replication. If not specified, the
+  // "default" application profile will be used.
+  string app_profile_id = 7;
+
+  // The key of the row to which the conditional mutation should be applied.
+  bytes row_key = 2;
+
+  // The filter to be applied to the contents of the specified row. Depending
+  // on whether or not any results are yielded, either `true_mutations` or
+  // `false_mutations` will be executed. If unset, checks that the row contains
+  // any values at all.
+  RowFilter predicate_filter = 6;
+
+  // Changes to be atomically applied to the specified row if `predicate_filter`
+  // yields at least one cell when applied to `row_key`. Entries are applied in
+  // order, meaning that earlier mutations can be masked by later ones.
+  // Must contain at least one entry if `false_mutations` is empty, and at most
+  // 100000.
+  repeated Mutation true_mutations = 4;
+
+  // Changes to be atomically applied to the specified row if `predicate_filter`
+  // does not yield any cells when applied to `row_key`. Entries are applied in
+  // order, meaning that earlier mutations can be masked by later ones.
+  // Must contain at least one entry if `true_mutations` is empty, and at most
+  // 100000.
+  repeated Mutation false_mutations = 5;
+}
+
+// Response message for Bigtable.CheckAndMutateRow.
+message CheckAndMutateRowResponse {
+  // Whether or not the request's `predicate_filter` yielded any results for
+  // the specified row.
+  bool predicate_matched = 1;
+}
+
+// Request message for Bigtable.ReadModifyWriteRow.
+message ReadModifyWriteRowRequest {
+  // The unique name of the table to which the read/modify/write rules should be
+  // applied.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string table_name = 1;
+
+  // This value specifies routing for replication. If not specified, the
+  // "default" application profile will be used.
+  string app_profile_id = 4;
+
+  // The key of the row to which the read/modify/write rules should be applied.
+  bytes row_key = 2;
+
+  // Rules specifying how the specified row's contents are to be transformed
+  // into writes. Entries are applied in order, meaning that earlier rules will
+  // affect the results of later ones.
+  repeated ReadModifyWriteRule rules = 3;
+}
+
+// Response message for Bigtable.ReadModifyWriteRow.
+message ReadModifyWriteRowResponse {
+  // A Row containing the new contents of all cells modified by the request.
+  Row row = 1;
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_cluster_data.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_cluster_data.proto
new file mode 100644
index 000000000000..ca3b663d8661
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_cluster_data.proto
@@ -0,0 +1,94 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.cluster.v1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1;cluster";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableClusterDataProto";
+option java_package = "com.google.bigtable.admin.cluster.v1";
+
+
+// A physical location in which a particular project can allocate Cloud BigTable
+// resources.
+message Zone {
+  // Possible states of a zone.
+  enum Status {
+    // The state of the zone is unknown or unspecified.
+    UNKNOWN = 0;
+
+    // The zone is in a good state.
+    OK = 1;
+
+    // The zone is down for planned maintenance.
+    PLANNED_MAINTENANCE = 2;
+
+    // The zone is down for emergency or unplanned maintenance.
+    EMERGENCY_MAINENANCE = 3;
+  }
+
+  // A permanent unique identifier for the zone.
+  // Values are of the form projects/<project>/zones/[a-z][-a-z0-9]*
+  string name = 1;
+
+  // The name of this zone as it appears in UIs.
+  string display_name = 2;
+
+  // The current state of this zone.
+  Status status = 3;
+}
+
+// An isolated set of Cloud BigTable resources on which tables can be hosted.
+message Cluster {
+  // A permanent unique identifier for the cluster. For technical reasons, the
+  // zone in which the cluster resides is included here.
+  // Values are of the form
+  // projects/<project>/zones/<zone>/clusters/[a-z][-a-z0-9]*
+  string name = 1;
+
+  // The operation currently running on the cluster, if any.
+  // This cannot be set directly, only through CreateCluster, UpdateCluster,
+  // or UndeleteCluster. Calls to these methods will be rejected if
+  // "current_operation" is already set.
+  google.longrunning.Operation current_operation = 3;
+
+  // The descriptive name for this cluster as it appears in UIs.
+  // Must be unique per zone.
+  string display_name = 4;
+
+  // The number of serve nodes allocated to this cluster.
+  int32 serve_nodes = 5;
+
+  // What storage type to use for tables in this cluster. Only configurable at
+  // cluster creation time. If unspecified, STORAGE_SSD will be used.
+  StorageType default_storage_type = 8;
+}
+
+enum StorageType {
+  // The storage type used is unspecified.
+  STORAGE_UNSPECIFIED = 0;
+
+  // Data will be stored in SSD, providing low and consistent latencies.
+  STORAGE_SSD = 1;
+
+  // Data will be stored in HDD, providing high and less predictable
+  // latencies.
+  STORAGE_HDD = 2;
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_cluster_service.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_cluster_service.proto
new file mode 100644
index 000000000000..038fcc46397f
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_cluster_service.proto
@@ -0,0 +1,130 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.cluster.v1;
+
+import "google/api/annotations.proto";
+import "google/bigtable/admin/cluster/v1/bigtable_cluster_data.proto";
+import "google/bigtable/admin/cluster/v1/bigtable_cluster_service_messages.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1;cluster";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableClusterServicesProto";
+option java_package = "com.google.bigtable.admin.cluster.v1";
+
+
+// Service for managing zonal Cloud Bigtable resources.
+service BigtableClusterService {
+  // Lists the supported zones for the given project.
+  rpc ListZones(ListZonesRequest) returns (ListZonesResponse) {
+    option (google.api.http) = { get: "/v1/{name=projects/*}/zones" };
+  }
+
+  // Gets information about a particular cluster.
+  rpc GetCluster(GetClusterRequest) returns (Cluster) {
+    option (google.api.http) = { get: "/v1/{name=projects/*/zones/*/clusters/*}" };
+  }
+
+  // Lists all clusters in the given project, along with any zones for which
+  // cluster information could not be retrieved.
+  rpc ListClusters(ListClustersRequest) returns (ListClustersResponse) {
+    option (google.api.http) = { get: "/v1/{name=projects/*}/aggregated/clusters" };
+  }
+
+  // Creates a cluster and begins preparing it to begin serving. The returned
+  // cluster embeds as its "current_operation" a long-running operation which
+  // can be used to track the progress of turning up the new cluster.
+  // Immediately upon completion of this request:
+  //  * The cluster will be readable via the API, with all requested attributes
+  //    but no allocated resources.
+  // Until completion of the embedded operation:
+  //  * Cancelling the operation will render the cluster immediately unreadable
+  //    via the API.
+  //  * All other attempts to modify or delete the cluster will be rejected.
+  // Upon completion of the embedded operation:
+  //  * Billing for all successfully-allocated resources will begin (some types
+  //    may have lower than the requested levels).
+  //  * New tables can be created in the cluster.
+  //  * The cluster's allocated resource levels will be readable via the API.
+  // The embedded operation's "metadata" field type is
+  // [CreateClusterMetadata][google.bigtable.admin.cluster.v1.CreateClusterMetadata] The embedded operation's "response" field type is
+  // [Cluster][google.bigtable.admin.cluster.v1.Cluster], if successful.
+  rpc CreateCluster(CreateClusterRequest) returns (Cluster) {
+    option (google.api.http) = { post: "/v1/{name=projects/*/zones/*}/clusters" body: "*" };
+  }
+
+  // Updates a cluster, and begins allocating or releasing resources as
+  // requested. The returned cluster embeds as its "current_operation" a
+  // long-running operation which can be used to track the progress of updating
+  // the cluster.
+  // Immediately upon completion of this request:
+  //  * For resource types where a decrease in the cluster's allocation has been
+  //    requested, billing will be based on the newly-requested level.
+  // Until completion of the embedded operation:
+  //  * Cancelling the operation will set its metadata's "cancelled_at_time",
+  //    and begin restoring resources to their pre-request values. The operation
+  //    is guaranteed to succeed at undoing all resource changes, after which
+  //    point it will terminate with a CANCELLED status.
+  //  * All other attempts to modify or delete the cluster will be rejected.
+  //  * Reading the cluster via the API will continue to give the pre-request
+  //    resource levels.
+  // Upon completion of the embedded operation:
+  //  * Billing will begin for all successfully-allocated resources (some types
+  //    may have lower than the requested levels).
+  //  * All newly-reserved resources will be available for serving the cluster's
+  //    tables.
+  //  * The cluster's new resource levels will be readable via the API.
+  // [UpdateClusterMetadata][google.bigtable.admin.cluster.v1.UpdateClusterMetadata] The embedded operation's "response" field type is
+  // [Cluster][google.bigtable.admin.cluster.v1.Cluster], if successful.
+  rpc UpdateCluster(Cluster) returns (Cluster) {
+    option (google.api.http) = { put: "/v1/{name=projects/*/zones/*/clusters/*}" body: "*" };
+  }
+
+  // Marks a cluster and all of its tables for permanent deletion in 7 days.
+  // Immediately upon completion of the request:
+  //  * Billing will cease for all of the cluster's reserved resources.
+  //  * The cluster's "delete_time" field will be set 7 days in the future.
+  // Soon afterward:
+  //  * All tables within the cluster will become unavailable.
+  // Prior to the cluster's "delete_time":
+  //  * The cluster can be recovered with a call to UndeleteCluster.
+  //  * All other attempts to modify or delete the cluster will be rejected.
+  // At the cluster's "delete_time":
+  //  * The cluster and *all of its tables* will immediately and irrevocably
+  //    disappear from the API, and their data will be permanently deleted.
+  rpc DeleteCluster(DeleteClusterRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { delete: "/v1/{name=projects/*/zones/*/clusters/*}" };
+  }
+
+  // Cancels the scheduled deletion of an cluster and begins preparing it to
+  // resume serving. The returned operation will also be embedded as the
+  // cluster's "current_operation".
+  // Immediately upon completion of this request:
+  //  * The cluster's "delete_time" field will be unset, protecting it from
+  //    automatic deletion.
+  // Until completion of the returned operation:
+  //  * The operation cannot be cancelled.
+  // Upon completion of the returned operation:
+  //  * Billing for the cluster's resources will resume.
+  //  * All tables within the cluster will be available.
+  // [UndeleteClusterMetadata][google.bigtable.admin.cluster.v1.UndeleteClusterMetadata] The embedded operation's "response" field type is
+  // [Cluster][google.bigtable.admin.cluster.v1.Cluster], if successful.
+  rpc UndeleteCluster(UndeleteClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = { post: "/v1/{name=projects/*/zones/*/clusters/*}:undelete" body: "" };
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_cluster_service_messages.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_cluster_service_messages.proto
new file mode 100644
index 000000000000..518d14dac8e0
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_cluster_service_messages.proto
@@ -0,0 +1,141 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.cluster.v1;
+
+import "google/bigtable/admin/cluster/v1/bigtable_cluster_data.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1;cluster";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableClusterServiceMessagesProto";
+option java_package = "com.google.bigtable.admin.cluster.v1";
+
+
+// Request message for BigtableClusterService.ListZones.
+message ListZonesRequest {
+  // The unique name of the project for which a list of supported zones is
+  // requested.
+  // Values are of the form projects/<project>
+  string name = 1;
+}
+
+// Response message for BigtableClusterService.ListZones.
+message ListZonesResponse {
+  // The list of requested zones.
+  repeated Zone zones = 1;
+}
+
+// Request message for BigtableClusterService.GetCluster.
+message GetClusterRequest {
+  // The unique name of the requested cluster.
+  // Values are of the form projects/<project>/zones/<zone>/clusters/<cluster>
+  string name = 1;
+}
+
+// Request message for BigtableClusterService.ListClusters.
+message ListClustersRequest {
+  // The unique name of the project for which a list of clusters is requested.
+  // Values are of the form projects/<project>
+  string name = 1;
+}
+
+// Response message for BigtableClusterService.ListClusters.
+message ListClustersResponse {
+  // The list of requested Clusters.
+  repeated Cluster clusters = 1;
+
+  // The zones for which clusters could not be retrieved.
+  repeated Zone failed_zones = 2;
+}
+
+// Request message for BigtableClusterService.CreateCluster.
+message CreateClusterRequest {
+  // The unique name of the zone in which to create the cluster.
+  // Values are of the form projects/<project>/zones/<zone>
+  string name = 1;
+
+  // The id to be used when referring to the new cluster within its zone,
+  // e.g. just the "test-cluster" section of the full name
+  // "projects/<project>/zones/<zone>/clusters/test-cluster".
+  string cluster_id = 2;
+
+  // The cluster to create.
+  // The "name", "delete_time", and "current_operation" fields must be left
+  // blank.
+  Cluster cluster = 3;
+}
+
+// Metadata type for the operation returned by
+// BigtableClusterService.CreateCluster.
+message CreateClusterMetadata {
+  // The request which prompted the creation of this operation.
+  CreateClusterRequest original_request = 1;
+
+  // The time at which original_request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which this operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// Metadata type for the operation returned by
+// BigtableClusterService.UpdateCluster.
+message UpdateClusterMetadata {
+  // The request which prompted the creation of this operation.
+  Cluster original_request = 1;
+
+  // The time at which original_request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which this operation was cancelled. If set, this operation is
+  // in the process of undoing itself (which is guaranteed to succeed) and
+  // cannot be cancelled again.
+  google.protobuf.Timestamp cancel_time = 3;
+
+  // The time at which this operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 4;
+}
+
+// Request message for BigtableClusterService.DeleteCluster.
+message DeleteClusterRequest {
+  // The unique name of the cluster to be deleted.
+  // Values are of the form projects/<project>/zones/<zone>/clusters/<cluster>
+  string name = 1;
+}
+
+// Request message for BigtableClusterService.UndeleteCluster.
+message UndeleteClusterRequest {
+  // The unique name of the cluster to be un-deleted.
+  // Values are of the form projects/<project>/zones/<zone>/clusters/<cluster>
+  string name = 1;
+}
+
+// Metadata type for the operation returned by
+// BigtableClusterService.UndeleteCluster.
+message UndeleteClusterMetadata {
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 1;
+
+  // The time at which this operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 2;
+}
+
+// Metadata type for operations initiated by the V2 BigtableAdmin service.
+// More complete information for such operations is available via the V2 API.
+message V2OperationMetadata {
+
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_data.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_data.proto
new file mode 100644
index 000000000000..bd063a925f45
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_data.proto
@@ -0,0 +1,516 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.v1;
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/v1;bigtable";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableDataProto";
+option java_package = "com.google.bigtable.v1";
+
+
+// Specifies the complete (requested) contents of a single row of a table.
+// Rows which exceed 256MiB in size cannot be read in full.
+message Row {
+  // The unique key which identifies this row within its table. This is the same
+  // key that's used to identify the row in, for example, a MutateRowRequest.
+  // May contain any non-empty byte string up to 4KiB in length.
+  bytes key = 1;
+
+  // May be empty, but only if the entire row is empty.
+  // The mutual ordering of column families is not specified.
+  repeated Family families = 2;
+}
+
+// Specifies (some of) the contents of a single row/column family of a table.
+message Family {
+  // The unique key which identifies this family within its row. This is the
+  // same key that's used to identify the family in, for example, a RowFilter
+  // which sets its "family_name_regex_filter" field.
+  // Must match [-_.a-zA-Z0-9]+, except that AggregatingRowProcessors may
+  // produce cells in a sentinel family with an empty name.
+  // Must be no greater than 64 characters in length.
+  string name = 1;
+
+  // Must not be empty. Sorted in order of increasing "qualifier".
+  repeated Column columns = 2;
+}
+
+// Specifies (some of) the contents of a single row/column of a table.
+message Column {
+  // The unique key which identifies this column within its family. This is the
+  // same key that's used to identify the column in, for example, a RowFilter
+  // which sets its "column_qualifier_regex_filter" field.
+  // May contain any byte string, including the empty string, up to 16kiB in
+  // length.
+  bytes qualifier = 1;
+
+  // Must not be empty. Sorted in order of decreasing "timestamp_micros".
+  repeated Cell cells = 2;
+}
+
+// Specifies (some of) the contents of a single row/column/timestamp of a table.
+message Cell {
+  // The cell's stored timestamp, which also uniquely identifies it within
+  // its column.
+  // Values are always expressed in microseconds, but individual tables may set
+  // a coarser "granularity" to further restrict the allowed values. For
+  // example, a table which specifies millisecond granularity will only allow
+  // values of "timestamp_micros" which are multiples of 1000.
+  int64 timestamp_micros = 1;
+
+  // The value stored in the cell.
+  // May contain any byte string, including the empty string, up to 100MiB in
+  // length.
+  bytes value = 2;
+
+  // Labels applied to the cell by a [RowFilter][google.bigtable.v1.RowFilter].
+  repeated string labels = 3;
+}
+
+// Specifies a contiguous range of rows.
+message RowRange {
+  // Inclusive lower bound. If left empty, interpreted as the empty string.
+  bytes start_key = 2;
+
+  // Exclusive upper bound. If left empty, interpreted as infinity.
+  bytes end_key = 3;
+}
+
+// Specifies a non-contiguous set of rows.
+message RowSet {
+  // Single rows included in the set.
+  repeated bytes row_keys = 1;
+
+  // Contiguous row ranges included in the set.
+  repeated RowRange row_ranges = 2;
+}
+
+// Specifies a contiguous range of columns within a single column family.
+// The range spans from <column_family>:<start_qualifier> to
+// <column_family>:<end_qualifier>, where both bounds can be either inclusive or
+// exclusive.
+message ColumnRange {
+  // The name of the column family within which this range falls.
+  string family_name = 1;
+
+  // The column qualifier at which to start the range (within 'column_family').
+  // If neither field is set, interpreted as the empty string, inclusive.
+  oneof start_qualifier {
+    // Used when giving an inclusive lower bound for the range.
+    bytes start_qualifier_inclusive = 2;
+
+    // Used when giving an exclusive lower bound for the range.
+    bytes start_qualifier_exclusive = 3;
+  }
+
+  // The column qualifier at which to end the range (within 'column_family').
+  // If neither field is set, interpreted as the infinite string, exclusive.
+  oneof end_qualifier {
+    // Used when giving an inclusive upper bound for the range.
+    bytes end_qualifier_inclusive = 4;
+
+    // Used when giving an exclusive upper bound for the range.
+    bytes end_qualifier_exclusive = 5;
+  }
+}
+
+// Specified a contiguous range of microsecond timestamps.
+message TimestampRange {
+  // Inclusive lower bound. If left empty, interpreted as 0.
+  int64 start_timestamp_micros = 1;
+
+  // Exclusive upper bound. If left empty, interpreted as infinity.
+  int64 end_timestamp_micros = 2;
+}
+
+// Specifies a contiguous range of raw byte values.
+message ValueRange {
+  // The value at which to start the range.
+  // If neither field is set, interpreted as the empty string, inclusive.
+  oneof start_value {
+    // Used when giving an inclusive lower bound for the range.
+    bytes start_value_inclusive = 1;
+
+    // Used when giving an exclusive lower bound for the range.
+    bytes start_value_exclusive = 2;
+  }
+
+  // The value at which to end the range.
+  // If neither field is set, interpreted as the infinite string, exclusive.
+  oneof end_value {
+    // Used when giving an inclusive upper bound for the range.
+    bytes end_value_inclusive = 3;
+
+    // Used when giving an exclusive upper bound for the range.
+    bytes end_value_exclusive = 4;
+  }
+}
+
+// Takes a row as input and produces an alternate view of the row based on
+// specified rules. For example, a RowFilter might trim down a row to include
+// just the cells from columns matching a given regular expression, or might
+// return all the cells of a row but not their values. More complicated filters
+// can be composed out of these components to express requests such as, "within
+// every column of a particular family, give just the two most recent cells
+// which are older than timestamp X."
+//
+// There are two broad categories of RowFilters (true filters and transformers),
+// as well as two ways to compose simple filters into more complex ones
+// (chains and interleaves). They work as follows:
+//
+// * True filters alter the input row by excluding some of its cells wholesale
+// from the output row. An example of a true filter is the "value_regex_filter",
+// which excludes cells whose values don't match the specified pattern. All
+// regex true filters use RE2 syntax (https://github.com/google/re2/wiki/Syntax)
+// in raw byte mode (RE2::Latin1), and are evaluated as full matches. An
+// important point to keep in mind is that RE2(.) is equivalent by default to
+// RE2([^\n]), meaning that it does not match newlines. When attempting to match
+// an arbitrary byte, you should therefore use the escape sequence '\C', which
+// may need to be further escaped as '\\C' in your client language.
+//
+// * Transformers alter the input row by changing the values of some of its
+// cells in the output, without excluding them completely. Currently, the only
+// supported transformer is the "strip_value_transformer", which replaces every
+// cell's value with the empty string.
+//
+// * Chains and interleaves are described in more detail in the
+// RowFilter.Chain and RowFilter.Interleave documentation.
+//
+// The total serialized size of a RowFilter message must not
+// exceed 4096 bytes, and RowFilters may not be nested within each other
+// (in Chains or Interleaves) to a depth of more than 20.
+message RowFilter {
+  // A RowFilter which sends rows through several RowFilters in sequence.
+  message Chain {
+    // The elements of "filters" are chained together to process the input row:
+    // in row -> f(0) -> intermediate row -> f(1) -> ... -> f(N) -> out row
+    // The full chain is executed atomically.
+    repeated RowFilter filters = 1;
+  }
+
+  // A RowFilter which sends each row to each of several component
+  // RowFilters and interleaves the results.
+  message Interleave {
+    // The elements of "filters" all process a copy of the input row, and the
+    // results are pooled, sorted, and combined into a single output row.
+    // If multiple cells are produced with the same column and timestamp,
+    // they will all appear in the output row in an unspecified mutual order.
+    // Consider the following example, with three filters:
+    //
+    //                              input row
+    //                                  |
+    //        -----------------------------------------------------
+    //        |                         |                         |
+    //       f(0)                      f(1)                      f(2)
+    //        |                         |                         |
+    // 1: foo,bar,10,x             foo,bar,10,z              far,bar,7,a
+    // 2: foo,blah,11,z            far,blah,5,x              far,blah,5,x
+    //        |                         |                         |
+    //        -----------------------------------------------------
+    //                                  |
+    // 1:                        foo,bar,10,z     // could have switched with #2
+    // 2:                        foo,bar,10,x     // could have switched with #1
+    // 3:                        foo,blah,11,z
+    // 4:                        far,bar,7,a
+    // 5:                        far,blah,5,x     // identical to #6
+    // 6:                        far,blah,5,x     // identical to #5
+    // All interleaved filters are executed atomically.
+    repeated RowFilter filters = 1;
+  }
+
+  // A RowFilter which evaluates one of two possible RowFilters, depending on
+  // whether or not a predicate RowFilter outputs any cells from the input row.
+  //
+  // IMPORTANT NOTE: The predicate filter does not execute atomically with the
+  // true and false filters, which may lead to inconsistent or unexpected
+  // results. Additionally, Condition filters have poor performance, especially
+  // when filters are set for the false condition.
+  message Condition {
+    // If "predicate_filter" outputs any cells, then "true_filter" will be
+    // evaluated on the input row. Otherwise, "false_filter" will be evaluated.
+    RowFilter predicate_filter = 1;
+
+    // The filter to apply to the input row if "predicate_filter" returns any
+    // results. If not provided, no results will be returned in the true case.
+    RowFilter true_filter = 2;
+
+    // The filter to apply to the input row if "predicate_filter" does not
+    // return any results. If not provided, no results will be returned in the
+    // false case.
+    RowFilter false_filter = 3;
+  }
+
+  // Which of the possible RowFilter types to apply. If none are set, this
+  // RowFilter returns all cells in the input row.
+  oneof filter {
+    // Applies several RowFilters to the data in sequence, progressively
+    // narrowing the results.
+    Chain chain = 1;
+
+    // Applies several RowFilters to the data in parallel and combines the
+    // results.
+    Interleave interleave = 2;
+
+    // Applies one of two possible RowFilters to the data based on the output of
+    // a predicate RowFilter.
+    Condition condition = 3;
+
+    // ADVANCED USE ONLY.
+    // Hook for introspection into the RowFilter. Outputs all cells directly to
+    // the output of the read rather than to any parent filter. Consider the
+    // following example:
+    //
+    // Chain(
+    //   FamilyRegex("A"),
+    //   Interleave(
+    //     All(),
+    //     Chain(Label("foo"), Sink())
+    //   ),
+    //   QualifierRegex("B")
+    // )
+    //
+    //                         A,A,1,w
+    //                         A,B,2,x
+    //                         B,B,4,z
+    //                            |
+    //                     FamilyRegex("A")
+    //                            |
+    //                         A,A,1,w
+    //                         A,B,2,x
+    //                            |
+    //               +------------+-------------+
+    //               |                          |
+    //             All()                    Label(foo)
+    //               |                          |
+    //            A,A,1,w              A,A,1,w,labels:[foo]
+    //            A,B,2,x              A,B,2,x,labels:[foo]
+    //               |                          |
+    //               |                        Sink() --------------+
+    //               |                          |                  |
+    //               +------------+      x------+          A,A,1,w,labels:[foo]
+    //                            |                        A,B,2,x,labels:[foo]
+    //                         A,A,1,w                             |
+    //                         A,B,2,x                             |
+    //                            |                                |
+    //                    QualifierRegex("B")                      |
+    //                            |                                |
+    //                         A,B,2,x                             |
+    //                            |                                |
+    //                            +--------------------------------+
+    //                            |
+    //                         A,A,1,w,labels:[foo]
+    //                         A,B,2,x,labels:[foo]  // could be switched
+    //                         A,B,2,x               // could be switched
+    //
+    // Despite being excluded by the qualifier filter, a copy of every cell
+    // that reaches the sink is present in the final result.
+    //
+    // As with an [Interleave][google.bigtable.v1.RowFilter.Interleave],
+    // duplicate cells are possible, and appear in an unspecified mutual order.
+    // In this case we have a duplicate with column "A:B" and timestamp 2,
+    // because one copy passed through the all filter while the other was
+    // passed through the label and sink. Note that one copy has label "foo",
+    // while the other does not.
+    //
+    // Cannot be used within the `predicate_filter`, `true_filter`, or
+    // `false_filter` of a [Condition][google.bigtable.v1.RowFilter.Condition].
+    bool sink = 16;
+
+    // Matches all cells, regardless of input. Functionally equivalent to
+    // leaving `filter` unset, but included for completeness.
+    bool pass_all_filter = 17;
+
+    // Does not match any cells, regardless of input. Useful for temporarily
+    // disabling just part of a filter.
+    bool block_all_filter = 18;
+
+    // Matches only cells from rows whose keys satisfy the given RE2 regex. In
+    // other words, passes through the entire row when the key matches, and
+    // otherwise produces an empty row.
+    // Note that, since row keys can contain arbitrary bytes, the '\C' escape
+    // sequence must be used if a true wildcard is desired. The '.' character
+    // will not match the new line character '\n', which may be present in a
+    // binary key.
+    bytes row_key_regex_filter = 4;
+
+    // Matches all cells from a row with probability p, and matches no cells
+    // from the row with probability 1-p.
+    double row_sample_filter = 14;
+
+    // Matches only cells from columns whose families satisfy the given RE2
+    // regex. For technical reasons, the regex must not contain the ':'
+    // character, even if it is not being used as a literal.
+    // Note that, since column families cannot contain the new line character
+    // '\n', it is sufficient to use '.' as a full wildcard when matching
+    // column family names.
+    string family_name_regex_filter = 5;
+
+    // Matches only cells from columns whose qualifiers satisfy the given RE2
+    // regex.
+    // Note that, since column qualifiers can contain arbitrary bytes, the '\C'
+    // escape sequence must be used if a true wildcard is desired. The '.'
+    // character will not match the new line character '\n', which may be
+    // present in a binary qualifier.
+    bytes column_qualifier_regex_filter = 6;
+
+    // Matches only cells from columns within the given range.
+    ColumnRange column_range_filter = 7;
+
+    // Matches only cells with timestamps within the given range.
+    TimestampRange timestamp_range_filter = 8;
+
+    // Matches only cells with values that satisfy the given regular expression.
+    // Note that, since cell values can contain arbitrary bytes, the '\C' escape
+    // sequence must be used if a true wildcard is desired. The '.' character
+    // will not match the new line character '\n', which may be present in a
+    // binary value.
+    bytes value_regex_filter = 9;
+
+    // Matches only cells with values that fall within the given range.
+    ValueRange value_range_filter = 15;
+
+    // Skips the first N cells of each row, matching all subsequent cells.
+    // If duplicate cells are present, as is possible when using an Interleave,
+    // each copy of the cell is counted separately.
+    int32 cells_per_row_offset_filter = 10;
+
+    // Matches only the first N cells of each row.
+    // If duplicate cells are present, as is possible when using an Interleave,
+    // each copy of the cell is counted separately.
+    int32 cells_per_row_limit_filter = 11;
+
+    // Matches only the most recent N cells within each column. For example,
+    // if N=2, this filter would match column "foo:bar" at timestamps 10 and 9,
+    // skip all earlier cells in "foo:bar", and then begin matching again in
+    // column "foo:bar2".
+    // If duplicate cells are present, as is possible when using an Interleave,
+    // each copy of the cell is counted separately.
+    int32 cells_per_column_limit_filter = 12;
+
+    // Replaces each cell's value with the empty string.
+    bool strip_value_transformer = 13;
+
+    // Applies the given label to all cells in the output row. This allows
+    // the client to determine which results were produced from which part of
+    // the filter.
+    //
+    // Values must be at most 15 characters in length, and match the RE2
+    // pattern [a-z0-9\\-]+
+    //
+    // Due to a technical limitation, it is not currently possible to apply
+    // multiple labels to a cell. As a result, a Chain may have no more than
+    // one sub-filter which contains a apply_label_transformer. It is okay for
+    // an Interleave to contain multiple apply_label_transformers, as they will
+    // be applied to separate copies of the input. This may be relaxed in the
+    // future.
+    string apply_label_transformer = 19;
+  }
+}
+
+// Specifies a particular change to be made to the contents of a row.
+message Mutation {
+  // A Mutation which sets the value of the specified cell.
+  message SetCell {
+    // The name of the family into which new data should be written.
+    // Must match [-_.a-zA-Z0-9]+
+    string family_name = 1;
+
+    // The qualifier of the column into which new data should be written.
+    // Can be any byte string, including the empty string.
+    bytes column_qualifier = 2;
+
+    // The timestamp of the cell into which new data should be written.
+    // Use -1 for current Bigtable server time.
+    // Otherwise, the client should set this value itself, noting that the
+    // default value is a timestamp of zero if the field is left unspecified.
+    // Values must match the "granularity" of the table (e.g. micros, millis).
+    int64 timestamp_micros = 3;
+
+    // The value to be written into the specified cell.
+    bytes value = 4;
+  }
+
+  // A Mutation which deletes cells from the specified column, optionally
+  // restricting the deletions to a given timestamp range.
+  message DeleteFromColumn {
+    // The name of the family from which cells should be deleted.
+    // Must match [-_.a-zA-Z0-9]+
+    string family_name = 1;
+
+    // The qualifier of the column from which cells should be deleted.
+    // Can be any byte string, including the empty string.
+    bytes column_qualifier = 2;
+
+    // The range of timestamps within which cells should be deleted.
+    TimestampRange time_range = 3;
+  }
+
+  // A Mutation which deletes all cells from the specified column family.
+  message DeleteFromFamily {
+    // The name of the family from which cells should be deleted.
+    // Must match [-_.a-zA-Z0-9]+
+    string family_name = 1;
+  }
+
+  // A Mutation which deletes all cells from the containing row.
+  message DeleteFromRow {
+
+  }
+
+  // Which of the possible Mutation types to apply.
+  oneof mutation {
+    // Set a cell's value.
+    SetCell set_cell = 1;
+
+    // Deletes cells from a column.
+    DeleteFromColumn delete_from_column = 2;
+
+    // Deletes cells from a column family.
+    DeleteFromFamily delete_from_family = 3;
+
+    // Deletes cells from the entire row.
+    DeleteFromRow delete_from_row = 4;
+  }
+}
+
+// Specifies an atomic read/modify/write operation on the latest value of the
+// specified column.
+message ReadModifyWriteRule {
+  // The name of the family to which the read/modify/write should be applied.
+  // Must match [-_.a-zA-Z0-9]+
+  string family_name = 1;
+
+  // The qualifier of the column to which the read/modify/write should be
+  // applied.
+  // Can be any byte string, including the empty string.
+  bytes column_qualifier = 2;
+
+  // The rule used to determine the column's new latest value from its current
+  // latest value.
+  oneof rule {
+    // Rule specifying that "append_value" be appended to the existing value.
+    // If the targeted cell is unset, it will be treated as containing the
+    // empty string.
+    bytes append_value = 3;
+
+    // Rule specifying that "increment_amount" be added to the existing value.
+    // If the targeted cell is unset, it will be treated as containing a zero.
+    // Otherwise, the targeted cell must contain an 8-byte value (interpreted
+    // as a 64-bit big-endian signed integer), or the entire request will fail.
+    int64 increment_amount = 4;
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_instance_admin.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_instance_admin.proto
new file mode 100644
index 000000000000..ec992ea0f818
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_instance_admin.proto
@@ -0,0 +1,456 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.bigtable.admin.v2;
+
+import "google/api/annotations.proto";
+import "google/bigtable/admin/v2/instance.proto";
+import "google/iam/v1/iam_policy.proto";
+import "google/iam/v1/policy.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableInstanceAdminProto";
+option java_package = "com.google.bigtable.admin.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2";
+
+
+// Service for creating, configuring, and deleting Cloud Bigtable Instances and
+// Clusters. Provides access to the Instance and Cluster schemas only, not the
+// tables' metadata or data stored in those tables.
+service BigtableInstanceAdmin {
+  // Create an instance within a project.
+  rpc CreateInstance(CreateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*}/instances"
+      body: "*"
+    };
+  }
+
+  // Gets information about an instance.
+  rpc GetInstance(GetInstanceRequest) returns (Instance) {
+    option (google.api.http) = {
+      get: "/v2/{name=projects/*/instances/*}"
+    };
+  }
+
+  // Lists information about instances in a project.
+  rpc ListInstances(ListInstancesRequest) returns (ListInstancesResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*}/instances"
+    };
+  }
+
+  // Updates an instance within a project.
+  rpc UpdateInstance(Instance) returns (Instance) {
+    option (google.api.http) = {
+      put: "/v2/{name=projects/*/instances/*}"
+      body: "*"
+    };
+  }
+
+  // Partially updates an instance within a project.
+  rpc PartialUpdateInstance(PartialUpdateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v2/{instance.name=projects/*/instances/*}"
+      body: "instance"
+    };
+  }
+
+  // Delete an instance from a project.
+  rpc DeleteInstance(DeleteInstanceRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=projects/*/instances/*}"
+    };
+  }
+
+  // Creates a cluster within an instance.
+  rpc CreateCluster(CreateClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*/instances/*}/clusters"
+      body: "cluster"
+    };
+  }
+
+  // Gets information about a cluster.
+  rpc GetCluster(GetClusterRequest) returns (Cluster) {
+    option (google.api.http) = {
+      get: "/v2/{name=projects/*/instances/*/clusters/*}"
+    };
+  }
+
+  // Lists information about clusters in an instance.
+  rpc ListClusters(ListClustersRequest) returns (ListClustersResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*/instances/*}/clusters"
+    };
+  }
+
+  // Updates a cluster within an instance.
+  rpc UpdateCluster(Cluster) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      put: "/v2/{name=projects/*/instances/*/clusters/*}"
+      body: "*"
+    };
+  }
+
+  // Deletes a cluster from an instance.
+  rpc DeleteCluster(DeleteClusterRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=projects/*/instances/*/clusters/*}"
+    };
+  }
+
+  // Creates an app profile within an instance.
+  rpc CreateAppProfile(CreateAppProfileRequest) returns (AppProfile) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*/instances/*}/appProfiles"
+      body: "app_profile"
+    };
+  }
+
+  // Gets information about an app profile.
+  rpc GetAppProfile(GetAppProfileRequest) returns (AppProfile) {
+    option (google.api.http) = {
+      get: "/v2/{name=projects/*/instances/*/appProfiles/*}"
+    };
+  }
+
+  // Lists information about app profiles in an instance.
+  rpc ListAppProfiles(ListAppProfilesRequest) returns (ListAppProfilesResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*/instances/*}/appProfiles"
+    };
+  }
+
+  // Updates an app profile within an instance.
+  rpc UpdateAppProfile(UpdateAppProfileRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v2/{app_profile.name=projects/*/instances/*/appProfiles/*}"
+      body: "app_profile"
+    };
+  }
+
+  // Deletes an app profile from an instance.
+  rpc DeleteAppProfile(DeleteAppProfileRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=projects/*/instances/*/appProfiles/*}"
+    };
+  }
+
+  // Gets the access control policy for an instance resource. Returns an empty
+  // policy if an instance exists but does not have a policy set.
+  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v2/{resource=projects/*/instances/*}:getIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Sets the access control policy on an instance resource. Replaces any
+  // existing policy.
+  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v2/{resource=projects/*/instances/*}:setIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Returns permissions that the caller has on the specified instance resource.
+  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) {
+    option (google.api.http) = {
+      post: "/v2/{resource=projects/*/instances/*}:testIamPermissions"
+      body: "*"
+    };
+  }
+}
+
+// Request message for BigtableInstanceAdmin.CreateInstance.
+message CreateInstanceRequest {
+  // The unique name of the project in which to create the new instance.
+  // Values are of the form `projects/<project>`.
+  string parent = 1;
+
+  // The ID to be used when referring to the new instance within its project,
+  // e.g., just `myinstance` rather than
+  // `projects/myproject/instances/myinstance`.
+  string instance_id = 2;
+
+  // The instance to create.
+  // Fields marked `OutputOnly` must be left blank.
+  Instance instance = 3;
+
+  // The clusters to be created within the instance, mapped by desired
+  // cluster ID, e.g., just `mycluster` rather than
+  // `projects/myproject/instances/myinstance/clusters/mycluster`.
+  // Fields marked `OutputOnly` must be left blank.
+  // Currently, at most two clusters can be specified.
+  map<string, Cluster> clusters = 4;
+}
+
+// Request message for BigtableInstanceAdmin.GetInstance.
+message GetInstanceRequest {
+  // The unique name of the requested instance. Values are of the form
+  // `projects/<project>/instances/<instance>`.
+  string name = 1;
+}
+
+// Request message for BigtableInstanceAdmin.ListInstances.
+message ListInstancesRequest {
+  // The unique name of the project for which a list of instances is requested.
+  // Values are of the form `projects/<project>`.
+  string parent = 1;
+
+  // DEPRECATED: This field is unused and ignored.
+  string page_token = 2;
+}
+
+// Response message for BigtableInstanceAdmin.ListInstances.
+message ListInstancesResponse {
+  // The list of requested instances.
+  repeated Instance instances = 1;
+
+  // Locations from which Instance information could not be retrieved,
+  // due to an outage or some other transient condition.
+  // Instances whose Clusters are all in one of the failed locations
+  // may be missing from `instances`, and Instances with at least one
+  // Cluster in a failed location may only have partial information returned.
+  // Values are of the form `projects/<project>/locations/<zone_id>`
+  repeated string failed_locations = 2;
+
+  // DEPRECATED: This field is unused and ignored.
+  string next_page_token = 3;
+}
+
+// Request message for BigtableInstanceAdmin.PartialUpdateInstance.
+message PartialUpdateInstanceRequest {
+  // The Instance which will (partially) replace the current value.
+  Instance instance = 1;
+
+  // The subset of Instance fields which should be replaced.
+  // Must be explicitly set.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for BigtableInstanceAdmin.DeleteInstance.
+message DeleteInstanceRequest {
+  // The unique name of the instance to be deleted.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string name = 1;
+}
+
+// Request message for BigtableInstanceAdmin.CreateCluster.
+message CreateClusterRequest {
+  // The unique name of the instance in which to create the new cluster.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // The ID to be used when referring to the new cluster within its instance,
+  // e.g., just `mycluster` rather than
+  // `projects/myproject/instances/myinstance/clusters/mycluster`.
+  string cluster_id = 2;
+
+  // The cluster to be created.
+  // Fields marked `OutputOnly` must be left blank.
+  Cluster cluster = 3;
+}
+
+// Request message for BigtableInstanceAdmin.GetCluster.
+message GetClusterRequest {
+  // The unique name of the requested cluster. Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>`.
+  string name = 1;
+}
+
+// Request message for BigtableInstanceAdmin.ListClusters.
+message ListClustersRequest {
+  // The unique name of the instance for which a list of clusters is requested.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  // Use `<instance> = '-'` to list Clusters for all Instances in a project,
+  // e.g., `projects/myproject/instances/-`.
+  string parent = 1;
+
+  // DEPRECATED: This field is unused and ignored.
+  string page_token = 2;
+}
+
+// Response message for BigtableInstanceAdmin.ListClusters.
+message ListClustersResponse {
+  // The list of requested clusters.
+  repeated Cluster clusters = 1;
+
+  // Locations from which Cluster information could not be retrieved,
+  // due to an outage or some other transient condition.
+  // Clusters from these locations may be missing from `clusters`,
+  // or may only have partial information returned.
+  // Values are of the form `projects/<project>/locations/<zone_id>`
+  repeated string failed_locations = 2;
+
+  // DEPRECATED: This field is unused and ignored.
+  string next_page_token = 3;
+}
+
+// Request message for BigtableInstanceAdmin.DeleteCluster.
+message DeleteClusterRequest {
+  // The unique name of the cluster to be deleted. Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>`.
+  string name = 1;
+}
+
+// The metadata for the Operation returned by CreateInstance.
+message CreateInstanceMetadata {
+  // The request that prompted the initiation of this CreateInstance operation.
+  CreateInstanceRequest original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// The metadata for the Operation returned by UpdateInstance.
+message UpdateInstanceMetadata {
+  // The request that prompted the initiation of this UpdateInstance operation.
+  PartialUpdateInstanceRequest original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// The metadata for the Operation returned by CreateCluster.
+message CreateClusterMetadata {
+  // The request that prompted the initiation of this CreateCluster operation.
+  CreateClusterRequest original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// The metadata for the Operation returned by UpdateCluster.
+message UpdateClusterMetadata {
+  // The request that prompted the initiation of this UpdateCluster operation.
+  Cluster original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// Request message for BigtableInstanceAdmin.CreateAppProfile.
+message CreateAppProfileRequest {
+  // The unique name of the instance in which to create the new app profile.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // The ID to be used when referring to the new app profile within its
+  // instance, e.g., just `myprofile` rather than
+  // `projects/myproject/instances/myinstance/appProfiles/myprofile`.
+  string app_profile_id = 2;
+
+  // The app profile to be created.
+  // Fields marked `OutputOnly` will be ignored.
+  AppProfile app_profile = 3;
+
+  // If true, ignore safety checks when creating the app profile.
+  bool ignore_warnings = 4;
+}
+
+// Request message for BigtableInstanceAdmin.GetAppProfile.
+message GetAppProfileRequest {
+  // The unique name of the requested app profile. Values are of the form
+  // `projects/<project>/instances/<instance>/appProfiles/<app_profile>`.
+  string name = 1;
+}
+
+// Request message for BigtableInstanceAdmin.ListAppProfiles.
+message ListAppProfilesRequest {
+  // The unique name of the instance for which a list of app profiles is
+  // requested. Values are of the form
+  // `projects/<project>/instances/<instance>`.
+  // Use `<instance> = '-'` to list AppProfiles for all Instances in a project,
+  // e.g., `projects/myproject/instances/-`.
+  string parent = 1;
+
+  // Maximum number of results per page.
+  // CURRENTLY UNIMPLEMENTED AND IGNORED.
+  int32 page_size = 3;
+
+  // The value of `next_page_token` returned by a previous call.
+  string page_token = 2;
+}
+
+// Response message for BigtableInstanceAdmin.ListAppProfiles.
+message ListAppProfilesResponse {
+  // The list of requested app profiles.
+  repeated AppProfile app_profiles = 1;
+
+  // Set if not all app profiles could be returned in a single response.
+  // Pass this value to `page_token` in another request to get the next
+  // page of results.
+  string next_page_token = 2;
+
+  // Locations from which AppProfile information could not be retrieved,
+  // due to an outage or some other transient condition.
+  // AppProfiles from these locations may be missing from `app_profiles`.
+  // Values are of the form `projects/<project>/locations/<zone_id>`
+  repeated string failed_locations = 3;
+}
+
+// Request message for BigtableInstanceAdmin.UpdateAppProfile.
+message UpdateAppProfileRequest {
+  // The app profile which will (partially) replace the current value.
+  AppProfile app_profile = 1;
+
+  // The subset of app profile fields which should be replaced.
+  // If unset, all fields will be replaced.
+  google.protobuf.FieldMask update_mask = 2;
+
+  // If true, ignore safety checks when updating the app profile.
+  bool ignore_warnings = 3;
+}
+
+
+// Request message for BigtableInstanceAdmin.DeleteAppProfile.
+message DeleteAppProfileRequest {
+  // The unique name of the app profile to be deleted. Values are of the form
+  // `projects/<project>/instances/<instance>/appProfiles/<app_profile>`.
+  string name = 1;
+
+  // If true, ignore safety checks when deleting the app profile.
+  bool ignore_warnings = 2;
+}
+
+// The metadata for the Operation returned by UpdateAppProfile.
+message UpdateAppProfileMetadata {
+
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_service.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_service.proto
new file mode 100644
index 000000000000..b1f729517a47
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_service.proto
@@ -0,0 +1,91 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.v1;
+
+import "google/api/annotations.proto";
+import "google/bigtable/v1/bigtable_data.proto";
+import "google/bigtable/v1/bigtable_service_messages.proto";
+import "google/protobuf/empty.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/v1;bigtable";
+option java_generic_services = true;
+option java_multiple_files = true;
+option java_outer_classname = "BigtableServicesProto";
+option java_package = "com.google.bigtable.v1";
+
+
+// Service for reading from and writing to existing Bigtables.
+service BigtableService {
+  // Streams back the contents of all requested rows, optionally applying
+  // the same Reader filter to each. Depending on their size, rows may be
+  // broken up across multiple responses, but atomicity of each row will still
+  // be preserved.
+  rpc ReadRows(ReadRowsRequest) returns (stream ReadRowsResponse) {
+    option (google.api.http) = {
+      post: "/v1/{table_name=projects/*/zones/*/clusters/*/tables/*}/rows:read"
+      body: "*"
+    };
+  }
+
+  // Returns a sample of row keys in the table. The returned row keys will
+  // delimit contiguous sections of the table of approximately equal size,
+  // which can be used to break up the data for distributed tasks like
+  // mapreduces.
+  rpc SampleRowKeys(SampleRowKeysRequest) returns (stream SampleRowKeysResponse) {
+    option (google.api.http) = {
+      get: "/v1/{table_name=projects/*/zones/*/clusters/*/tables/*}/rows:sampleKeys"
+    };
+  }
+
+  // Mutates a row atomically. Cells already present in the row are left
+  // unchanged unless explicitly changed by 'mutation'.
+  rpc MutateRow(MutateRowRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1/{table_name=projects/*/zones/*/clusters/*/tables/*}/rows/{row_key}:mutate"
+      body: "*"
+    };
+  }
+
+  // Mutates multiple rows in a batch. Each individual row is mutated
+  // atomically as in MutateRow, but the entire batch is not executed
+  // atomically.
+  rpc MutateRows(MutateRowsRequest) returns (MutateRowsResponse) {
+    option (google.api.http) = {
+      post: "/v1/{table_name=projects/*/zones/*/clusters/*/tables/*}:mutateRows"
+      body: "*"
+    };
+  }
+
+  // Mutates a row atomically based on the output of a predicate Reader filter.
+  rpc CheckAndMutateRow(CheckAndMutateRowRequest) returns (CheckAndMutateRowResponse) {
+    option (google.api.http) = {
+      post: "/v1/{table_name=projects/*/zones/*/clusters/*/tables/*}/rows/{row_key}:checkAndMutate"
+      body: "*"
+    };
+  }
+
+  // Modifies a row atomically, reading the latest existing timestamp/value from
+  // the specified columns and writing a new value at
+  // max(existing timestamp, current server time) based on pre-defined
+  // read/modify/write rules. Returns the new contents of all modified cells.
+  rpc ReadModifyWriteRow(ReadModifyWriteRowRequest) returns (Row) {
+    option (google.api.http) = {
+      post: "/v1/{table_name=projects/*/zones/*/clusters/*/tables/*}/rows/{row_key}:readModifyWrite"
+      body: "*"
+    };
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_service_messages.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_service_messages.proto
new file mode 100644
index 000000000000..d734ececaec3
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_service_messages.proto
@@ -0,0 +1,218 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.v1;
+
+import "google/bigtable/v1/bigtable_data.proto";
+import "google/rpc/status.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/v1;bigtable";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableServiceMessagesProto";
+option java_package = "com.google.bigtable.v1";
+
+
+// Request message for BigtableServer.ReadRows.
+message ReadRowsRequest {
+  // The unique name of the table from which to read.
+  string table_name = 1;
+
+  // If neither row_key nor row_range is set, reads from all rows.
+  oneof target {
+    // The key of a single row from which to read.
+    bytes row_key = 2;
+
+    // A range of rows from which to read.
+    RowRange row_range = 3;
+
+    // A set of rows from which to read. Entries need not be in order, and will
+    // be deduplicated before reading.
+    // The total serialized size of the set must not exceed 1MB.
+    RowSet row_set = 8;
+  }
+
+  // The filter to apply to the contents of the specified row(s). If unset,
+  // reads the entire table.
+  RowFilter filter = 5;
+
+  // By default, rows are read sequentially, producing results which are
+  // guaranteed to arrive in increasing row order. Setting
+  // "allow_row_interleaving" to true allows multiple rows to be interleaved in
+  // the response stream, which increases throughput but breaks this guarantee,
+  // and may force the client to use more memory to buffer partially-received
+  // rows. Cannot be set to true when specifying "num_rows_limit".
+  bool allow_row_interleaving = 6;
+
+  // The read will terminate after committing to N rows' worth of results. The
+  // default (zero) is to return all results.
+  // Note that "allow_row_interleaving" cannot be set to true when this is set.
+  int64 num_rows_limit = 7;
+}
+
+// Response message for BigtableService.ReadRows.
+message ReadRowsResponse {
+  // Specifies a piece of a row's contents returned as part of the read
+  // response stream.
+  message Chunk {
+    oneof chunk {
+      // A subset of the data from a particular row. As long as no "reset_row"
+      // is received in between, multiple "row_contents" from the same row are
+      // from the same atomic view of that row, and will be received in the
+      // expected family/column/timestamp order.
+      Family row_contents = 1;
+
+      // Indicates that the client should drop all previous chunks for
+      // "row_key", as it will be re-read from the beginning.
+      bool reset_row = 2;
+
+      // Indicates that the client can safely process all previous chunks for
+      // "row_key", as its data has been fully read.
+      bool commit_row = 3;
+    }
+  }
+
+  // The key of the row for which we're receiving data.
+  // Results will be received in increasing row key order, unless
+  // "allow_row_interleaving" was specified in the request.
+  bytes row_key = 1;
+
+  // One or more chunks of the row specified by "row_key".
+  repeated Chunk chunks = 2;
+}
+
+// Request message for BigtableService.SampleRowKeys.
+message SampleRowKeysRequest {
+  // The unique name of the table from which to sample row keys.
+  string table_name = 1;
+}
+
+// Response message for BigtableService.SampleRowKeys.
+message SampleRowKeysResponse {
+  // Sorted streamed sequence of sample row keys in the table. The table might
+  // have contents before the first row key in the list and after the last one,
+  // but a key containing the empty string indicates "end of table" and will be
+  // the last response given, if present.
+  // Note that row keys in this list may not have ever been written to or read
+  // from, and users should therefore not make any assumptions about the row key
+  // structure that are specific to their use case.
+  bytes row_key = 1;
+
+  // Approximate total storage space used by all rows in the table which precede
+  // "row_key". Buffering the contents of all rows between two subsequent
+  // samples would require space roughly equal to the difference in their
+  // "offset_bytes" fields.
+  int64 offset_bytes = 2;
+}
+
+// Request message for BigtableService.MutateRow.
+message MutateRowRequest {
+  // The unique name of the table to which the mutation should be applied.
+  string table_name = 1;
+
+  // The key of the row to which the mutation should be applied.
+  bytes row_key = 2;
+
+  // Changes to be atomically applied to the specified row. Entries are applied
+  // in order, meaning that earlier mutations can be masked by later ones.
+  // Must contain at least one entry and at most 100000.
+  repeated Mutation mutations = 3;
+}
+
+// Request message for BigtableService.MutateRows.
+message MutateRowsRequest {
+  message Entry {
+    // The key of the row to which the `mutations` should be applied.
+    bytes row_key = 1;
+
+    // Changes to be atomically applied to the specified row. Mutations are
+    // applied in order, meaning that earlier mutations can be masked by
+    // later ones.
+    // At least one mutation must be specified.
+    repeated Mutation mutations = 2;
+  }
+
+  // The unique name of the table to which the mutations should be applied.
+  string table_name = 1;
+
+  // The row keys/mutations to be applied in bulk.
+  // Each entry is applied as an atomic mutation, but the entries may be
+  // applied in arbitrary order (even between entries for the same row).
+  // At least one entry must be specified, and in total the entries may
+  // contain at most 100000 mutations.
+  repeated Entry entries = 2;
+}
+
+// Response message for BigtableService.MutateRows.
+message MutateRowsResponse {
+  // The results for each Entry from the request, presented in the order
+  // in which the entries were originally given.
+  // Depending on how requests are batched during execution, it is possible
+  // for one Entry to fail due to an error with another Entry. In the event
+  // that this occurs, the same error will be reported for both entries.
+  repeated google.rpc.Status statuses = 1;
+}
+
+// Request message for BigtableService.CheckAndMutateRowRequest
+message CheckAndMutateRowRequest {
+  // The unique name of the table to which the conditional mutation should be
+  // applied.
+  string table_name = 1;
+
+  // The key of the row to which the conditional mutation should be applied.
+  bytes row_key = 2;
+
+  // The filter to be applied to the contents of the specified row. Depending
+  // on whether or not any results are yielded, either "true_mutations" or
+  // "false_mutations" will be executed. If unset, checks that the row contains
+  // any values at all.
+  RowFilter predicate_filter = 6;
+
+  // Changes to be atomically applied to the specified row if "predicate_filter"
+  // yields at least one cell when applied to "row_key". Entries are applied in
+  // order, meaning that earlier mutations can be masked by later ones.
+  // Must contain at least one entry if "false_mutations" is empty, and at most
+  // 100000.
+  repeated Mutation true_mutations = 4;
+
+  // Changes to be atomically applied to the specified row if "predicate_filter"
+  // does not yield any cells when applied to "row_key". Entries are applied in
+  // order, meaning that earlier mutations can be masked by later ones.
+  // Must contain at least one entry if "true_mutations" is empty, and at most
+  // 100000.
+  repeated Mutation false_mutations = 5;
+}
+
+// Response message for BigtableService.CheckAndMutateRowRequest.
+message CheckAndMutateRowResponse {
+  // Whether or not the request's "predicate_filter" yielded any results for
+  // the specified row.
+  bool predicate_matched = 1;
+}
+
+// Request message for BigtableService.ReadModifyWriteRowRequest.
+message ReadModifyWriteRowRequest {
+  // The unique name of the table to which the read/modify/write rules should be
+  // applied.
+  string table_name = 1;
+
+  // The key of the row to which the read/modify/write rules should be applied.
+  bytes row_key = 2;
+
+  // Rules specifying how the specified row's contents are to be transformed
+  // into writes. Entries are applied in order, meaning that earlier rules will
+  // affect the results of later ones.
+  repeated ReadModifyWriteRule rules = 3;
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_admin.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_admin.proto
new file mode 100644
index 000000000000..2d5bddf302aa
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_admin.proto
@@ -0,0 +1,525 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.bigtable.admin.v2;
+
+import "google/api/annotations.proto";
+import "google/bigtable/admin/v2/table.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableTableAdminProto";
+option java_package = "com.google.bigtable.admin.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2";
+
+
+// Service for creating, configuring, and deleting Cloud Bigtable tables.
+//
+//
+// Provides access to the table schemas only, not the data stored within
+// the tables.
+service BigtableTableAdmin {
+  // Creates a new table in the specified instance.
+  // The table can be created with a full set of initial column families,
+  // specified in the request.
+  rpc CreateTable(CreateTableRequest) returns (Table) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*/instances/*}/tables"
+      body: "*"
+    };
+  }
+
+  // Creates a new table from the specified snapshot. The target table must
+  // not exist. The snapshot and the table must be in the same instance.
+  //
+  // Note: This is a private alpha release of Cloud Bigtable snapshots. This
+  // feature is not currently available to most Cloud Bigtable customers. This
+  // feature might be changed in backward-incompatible ways and is not
+  // recommended for production use. It is not subject to any SLA or deprecation
+  // policy.
+  rpc CreateTableFromSnapshot(CreateTableFromSnapshotRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*/instances/*}/tables:createFromSnapshot"
+      body: "*"
+    };
+  }
+
+  // Lists all tables served from a specified instance.
+  rpc ListTables(ListTablesRequest) returns (ListTablesResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*/instances/*}/tables"
+    };
+  }
+
+  // Gets metadata information about the specified table.
+  rpc GetTable(GetTableRequest) returns (Table) {
+    option (google.api.http) = {
+      get: "/v2/{name=projects/*/instances/*/tables/*}"
+    };
+  }
+
+  // Permanently deletes a specified table and all of its data.
+  rpc DeleteTable(DeleteTableRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=projects/*/instances/*/tables/*}"
+    };
+  }
+
+  // Performs a series of column family modifications on the specified table.
+  // Either all or none of the modifications will occur before this method
+  // returns, but data requests received prior to that point may see a table
+  // where only some modifications have taken effect.
+  rpc ModifyColumnFamilies(ModifyColumnFamiliesRequest) returns (Table) {
+    option (google.api.http) = {
+      post: "/v2/{name=projects/*/instances/*/tables/*}:modifyColumnFamilies"
+      body: "*"
+    };
+  }
+
+  // Permanently drop/delete a row range from a specified table. The request can
+  // specify whether to delete all rows in a table, or only those that match a
+  // particular prefix.
+  rpc DropRowRange(DropRowRangeRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v2/{name=projects/*/instances/*/tables/*}:dropRowRange"
+      body: "*"
+    };
+  }
+
+  // Generates a consistency token for a Table, which can be used in
+  // CheckConsistency to check whether mutations to the table that finished
+  // before this call started have been replicated. The tokens will be available
+  // for 90 days.
+  rpc GenerateConsistencyToken(GenerateConsistencyTokenRequest) returns (GenerateConsistencyTokenResponse) {
+    option (google.api.http) = {
+      post: "/v2/{name=projects/*/instances/*/tables/*}:generateConsistencyToken"
+      body: "*"
+    };
+  }
+
+  // Checks replication consistency based on a consistency token, that is, if
+  // replication has caught up based on the conditions specified in the token
+  // and the check request.
+  rpc CheckConsistency(CheckConsistencyRequest) returns (CheckConsistencyResponse) {
+    option (google.api.http) = {
+      post: "/v2/{name=projects/*/instances/*/tables/*}:checkConsistency"
+      body: "*"
+    };
+  }
+
+  // Creates a new snapshot in the specified cluster from the specified
+  // source table. The cluster and the table must be in the same instance.
+  //
+  // Note: This is a private alpha release of Cloud Bigtable snapshots. This
+  // feature is not currently available to most Cloud Bigtable customers. This
+  // feature might be changed in backward-incompatible ways and is not
+  // recommended for production use. It is not subject to any SLA or deprecation
+  // policy.
+  rpc SnapshotTable(SnapshotTableRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v2/{name=projects/*/instances/*/tables/*}:snapshot"
+      body: "*"
+    };
+  }
+
+  // Gets metadata information about the specified snapshot.
+  //
+  // Note: This is a private alpha release of Cloud Bigtable snapshots. This
+  // feature is not currently available to most Cloud Bigtable customers. This
+  // feature might be changed in backward-incompatible ways and is not
+  // recommended for production use. It is not subject to any SLA or deprecation
+  // policy.
+  rpc GetSnapshot(GetSnapshotRequest) returns (Snapshot) {
+    option (google.api.http) = {
+      get: "/v2/{name=projects/*/instances/*/clusters/*/snapshots/*}"
+    };
+  }
+
+  // Lists all snapshots associated with the specified cluster.
+  //
+  // Note: This is a private alpha release of Cloud Bigtable snapshots. This
+  // feature is not currently available to most Cloud Bigtable customers. This
+  // feature might be changed in backward-incompatible ways and is not
+  // recommended for production use. It is not subject to any SLA or deprecation
+  // policy.
+  rpc ListSnapshots(ListSnapshotsRequest) returns (ListSnapshotsResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*/instances/*/clusters/*}/snapshots"
+    };
+  }
+
+  // Permanently deletes the specified snapshot.
+  //
+  // Note: This is a private alpha release of Cloud Bigtable snapshots. This
+  // feature is not currently available to most Cloud Bigtable customers. This
+  // feature might be changed in backward-incompatible ways and is not
+  // recommended for production use. It is not subject to any SLA or deprecation
+  // policy.
+  rpc DeleteSnapshot(DeleteSnapshotRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=projects/*/instances/*/clusters/*/snapshots/*}"
+    };
+  }
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.CreateTable][google.bigtable.admin.v2.BigtableTableAdmin.CreateTable]
+message CreateTableRequest {
+  // An initial split point for a newly created table.
+  message Split {
+    // Row key to use as an initial tablet boundary.
+    bytes key = 1;
+  }
+
+  // The unique name of the instance in which to create the table.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // The name by which the new table should be referred to within the parent
+  // instance, e.g., `foobar` rather than `<parent>/tables/foobar`.
+  string table_id = 2;
+
+  // The Table to create.
+  Table table = 3;
+
+  // The optional list of row keys that will be used to initially split the
+  // table into several tablets (tablets are similar to HBase regions).
+  // Given two split keys, `s1` and `s2`, three tablets will be created,
+  // spanning the key ranges: `[, s1), [s1, s2), [s2, )`.
+  //
+  // Example:
+  //
+  // * Row keys := `["a", "apple", "custom", "customer_1", "customer_2",`
+  //                `"other", "zz"]`
+  // * initial_split_keys := `["apple", "customer_1", "customer_2", "other"]`
+  // * Key assignment:
+  //     - Tablet 1 `[, apple)                => {"a"}.`
+  //     - Tablet 2 `[apple, customer_1)      => {"apple", "custom"}.`
+  //     - Tablet 3 `[customer_1, customer_2) => {"customer_1"}.`
+  //     - Tablet 4 `[customer_2, other)      => {"customer_2"}.`
+  //     - Tablet 5 `[other, )                => {"other", "zz"}.`
+  repeated Split initial_splits = 4;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message CreateTableFromSnapshotRequest {
+  // The unique name of the instance in which to create the table.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // The name by which the new table should be referred to within the parent
+  // instance, e.g., `foobar` rather than `<parent>/tables/foobar`.
+  string table_id = 2;
+
+  // The unique name of the snapshot from which to restore the table. The
+  // snapshot and the table must be in the same instance.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>/snapshots/<snapshot>`.
+  string source_snapshot = 3;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange][google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange]
+message DropRowRangeRequest {
+  // The unique name of the table on which to drop a range of rows.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+
+  // Delete all rows or by prefix.
+  oneof target {
+    // Delete all rows that start with this row key prefix. Prefix cannot be
+    // zero length.
+    bytes row_key_prefix = 2;
+
+    // Delete all rows in the table. Setting this to false is a no-op.
+    bool delete_all_data_from_table = 3;
+  }
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables]
+message ListTablesRequest {
+  // The unique name of the instance for which tables should be listed.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // The view to be applied to the returned tables' fields.
+  // Defaults to `NAME_ONLY` if unspecified; no others are currently supported.
+  Table.View view = 2;
+
+  // Maximum number of results per page.
+  // CURRENTLY UNIMPLEMENTED AND IGNORED.
+  int32 page_size = 4;
+
+  // The value of `next_page_token` returned by a previous call.
+  string page_token = 3;
+}
+
+// Response message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables]
+message ListTablesResponse {
+  // The tables present in the requested instance.
+  repeated Table tables = 1;
+
+  // Set if not all tables could be returned in a single response.
+  // Pass this value to `page_token` in another request to get the next
+  // page of results.
+  string next_page_token = 2;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.GetTable][google.bigtable.admin.v2.BigtableTableAdmin.GetTable]
+message GetTableRequest {
+  // The unique name of the requested table.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+
+  // The view to be applied to the returned table's fields.
+  // Defaults to `SCHEMA_VIEW` if unspecified.
+  Table.View view = 2;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable]
+message DeleteTableRequest {
+  // The unique name of the table to be deleted.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies][google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies]
+message ModifyColumnFamiliesRequest {
+  // A create, update, or delete of a particular column family.
+  message Modification {
+    // The ID of the column family to be modified.
+    string id = 1;
+
+    // Column familiy modifications.
+    oneof mod {
+      // Create a new column family with the specified schema, or fail if
+      // one already exists with the given ID.
+      ColumnFamily create = 2;
+
+      // Update an existing column family to the specified schema, or fail
+      // if no column family exists with the given ID.
+      ColumnFamily update = 3;
+
+      // Drop (delete) the column family with the given ID, or fail if no such
+      // family exists.
+      bool drop = 4;
+    }
+  }
+
+  // The unique name of the table whose families should be modified.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+
+  // Modifications to be atomically applied to the specified table's families.
+  // Entries are applied in order, meaning that earlier modifications can be
+  // masked by later ones (in the case of repeated updates to the same family,
+  // for example).
+  repeated Modification modifications = 2;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+message GenerateConsistencyTokenRequest {
+  // The unique name of the Table for which to create a consistency token.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+}
+
+// Response message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+message GenerateConsistencyTokenResponse {
+  // The generated consistency token.
+  string consistency_token = 1;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+message CheckConsistencyRequest {
+  // The unique name of the Table for which to check replication consistency.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+
+  // The token created using GenerateConsistencyToken for the Table.
+  string consistency_token = 2;
+}
+
+// Response message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+message CheckConsistencyResponse {
+  // True only if the token is consistent. A token is consistent if replication
+  // has caught up with the restrictions specified in the request.
+  bool consistent = 1;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable][google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message SnapshotTableRequest {
+  // The unique name of the table to have the snapshot taken.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/tables/<table>`.
+  string name = 1;
+
+  // The name of the cluster where the snapshot will be created in.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>`.
+  string cluster = 2;
+
+  // The ID by which the new snapshot should be referred to within the parent
+  // cluster, e.g., `mysnapshot` of the form: `[_a-zA-Z0-9][-_.a-zA-Z0-9]*`
+  // rather than
+  // `projects/<project>/instances/<instance>/clusters/<cluster>/snapshots/mysnapshot`.
+  string snapshot_id = 3;
+
+  // The amount of time that the new snapshot can stay active after it is
+  // created. Once 'ttl' expires, the snapshot will get deleted. The maximum
+  // amount of time a snapshot can stay active is 7 days. If 'ttl' is not
+  // specified, the default value of 24 hours will be used.
+  google.protobuf.Duration ttl = 4;
+
+  // Description of the snapshot.
+  string description = 5;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message GetSnapshotRequest {
+  // The unique name of the requested snapshot.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>/snapshots/<snapshot>`.
+  string name = 1;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message ListSnapshotsRequest {
+  // The unique name of the cluster for which snapshots should be listed.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>`.
+  // Use `<cluster> = '-'` to list snapshots for all clusters in an instance,
+  // e.g., `projects/<project>/instances/<instance>/clusters/-`.
+  string parent = 1;
+
+  // The maximum number of snapshots to return per page.
+  // CURRENTLY UNIMPLEMENTED AND IGNORED.
+  int32 page_size = 2;
+
+  // The value of `next_page_token` returned by a previous call.
+  string page_token = 3;
+}
+
+// Response message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message ListSnapshotsResponse {
+  // The snapshots present in the requested cluster.
+  repeated Snapshot snapshots = 1;
+
+  // Set if not all snapshots could be returned in a single response.
+  // Pass this value to `page_token` in another request to get the next
+  // page of results.
+  string next_page_token = 2;
+}
+
+// Request message for
+// [google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot]
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message DeleteSnapshotRequest {
+  // The unique name of the snapshot to be deleted.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>/snapshots/<snapshot>`.
+  string name = 1;
+}
+
+// The metadata for the Operation returned by SnapshotTable.
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message SnapshotTableMetadata {
+  // The request that prompted the initiation of this SnapshotTable operation.
+  SnapshotTableRequest original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
+
+// The metadata for the Operation returned by CreateTableFromSnapshot.
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message CreateTableFromSnapshotMetadata {
+  // The request that prompted the initiation of this CreateTableFromSnapshot
+  // operation.
+  CreateTableFromSnapshotRequest original_request = 1;
+
+  // The time at which the original request was received.
+  google.protobuf.Timestamp request_time = 2;
+
+  // The time at which the operation failed or was completed successfully.
+  google.protobuf.Timestamp finish_time = 3;
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_data.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_data.proto
new file mode 100644
index 000000000000..e4efb74f560e
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_data.proto
@@ -0,0 +1,126 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.table.v1;
+
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/table/v1;table";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableTableDataProto";
+option java_package = "com.google.bigtable.admin.table.v1";
+
+
+// A collection of user data indexed by row, column, and timestamp.
+// Each table is served using the resources of its parent cluster.
+message Table {
+  enum TimestampGranularity {
+    MILLIS = 0;
+  }
+
+  // A unique identifier of the form
+  // <cluster_name>/tables/[_a-zA-Z0-9][-_.a-zA-Z0-9]*
+  string name = 1;
+
+  // If this Table is in the process of being created, the Operation used to
+  // track its progress. As long as this operation is present, the Table will
+  // not accept any Table Admin or Read/Write requests.
+  google.longrunning.Operation current_operation = 2;
+
+  // The column families configured for this table, mapped by column family id.
+  map<string, ColumnFamily> column_families = 3;
+
+  // The granularity (e.g. MILLIS, MICROS) at which timestamps are stored in
+  // this table. Timestamps not matching the granularity will be rejected.
+  // Cannot be changed once the table is created.
+  TimestampGranularity granularity = 4;
+}
+
+// A set of columns within a table which share a common configuration.
+message ColumnFamily {
+  // A unique identifier of the form <table_name>/columnFamilies/[-_.a-zA-Z0-9]+
+  // The last segment is the same as the "name" field in
+  // google.bigtable.v1.Family.
+  string name = 1;
+
+  // Garbage collection expression specified by the following grammar:
+  //   GC = EXPR
+  //      | "" ;
+  //   EXPR = EXPR, "||", EXPR              (* lowest precedence *)
+  //        | EXPR, "&&", EXPR
+  //        | "(", EXPR, ")"                (* highest precedence *)
+  //        | PROP ;
+  //   PROP = "version() >", NUM32
+  //        | "age() >", NUM64, [ UNIT ] ;
+  //   NUM32 = non-zero-digit { digit } ;    (* # NUM32 <= 2^32 - 1 *)
+  //   NUM64 = non-zero-digit { digit } ;    (* # NUM64 <= 2^63 - 1 *)
+  //   UNIT =  "d" | "h" | "m"  (* d=days, h=hours, m=minutes, else micros *)
+  // GC expressions can be up to 500 characters in length
+  //
+  // The different types of PROP are defined as follows:
+  //   version() - cell index, counting from most recent and starting at 1
+  //   age() - age of the cell (current time minus cell timestamp)
+  //
+  // Example: "version() > 3 || (age() > 3d && version() > 1)"
+  //   drop cells beyond the most recent three, and drop cells older than three
+  //   days unless they're the most recent cell in the row/column
+  //
+  // Garbage collection executes opportunistically in the background, and so
+  // it's possible for reads to return a cell even if it matches the active GC
+  // expression for its family.
+  string gc_expression = 2;
+
+  // Garbage collection rule specified as a protobuf.
+  // Supersedes `gc_expression`.
+  // Must serialize to at most 500 bytes.
+  //
+  // NOTE: Garbage collection executes opportunistically in the background, and
+  // so it's possible for reads to return a cell even if it matches the active
+  // GC expression for its family.
+  GcRule gc_rule = 3;
+}
+
+// Rule for determining which cells to delete during garbage collection.
+message GcRule {
+  // A GcRule which deletes cells matching all of the given rules.
+  message Intersection {
+    // Only delete cells which would be deleted by every element of `rules`.
+    repeated GcRule rules = 1;
+  }
+
+  // A GcRule which deletes cells matching any of the given rules.
+  message Union {
+    // Delete cells which would be deleted by any element of `rules`.
+    repeated GcRule rules = 1;
+  }
+
+  oneof rule {
+    // Delete all cells in a column except the most recent N.
+    int32 max_num_versions = 1;
+
+    // Delete cells in a column older than the given age.
+    // Values must be at least one millisecond, and will be truncated to
+    // microsecond granularity.
+    google.protobuf.Duration max_age = 2;
+
+    // Delete cells that would be deleted by every nested rule.
+    Intersection intersection = 3;
+
+    // Delete cells that would be deleted by any nested rule.
+    Union union = 4;
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_service.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_service.proto
new file mode 100644
index 000000000000..6e968fee17c1
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_service.proto
@@ -0,0 +1,80 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.table.v1;
+
+import "google/api/annotations.proto";
+import "google/bigtable/admin/table/v1/bigtable_table_data.proto";
+import "google/bigtable/admin/table/v1/bigtable_table_service_messages.proto";
+import "google/protobuf/empty.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/table/v1;table";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableTableServicesProto";
+option java_package = "com.google.bigtable.admin.table.v1";
+
+
+// Service for creating, configuring, and deleting Cloud Bigtable tables.
+// Provides access to the table schemas only, not the data stored within the tables.
+service BigtableTableService {
+  // Creates a new table, to be served from a specified cluster.
+  // The table can be created with a full set of initial column families,
+  // specified in the request.
+  rpc CreateTable(CreateTableRequest) returns (Table) {
+    option (google.api.http) = { post: "/v1/{name=projects/*/zones/*/clusters/*}/tables" body: "*" };
+  }
+
+  // Lists the names of all tables served from a specified cluster.
+  rpc ListTables(ListTablesRequest) returns (ListTablesResponse) {
+    option (google.api.http) = { get: "/v1/{name=projects/*/zones/*/clusters/*}/tables" };
+  }
+
+  // Gets the schema of the specified table, including its column families.
+  rpc GetTable(GetTableRequest) returns (Table) {
+    option (google.api.http) = { get: "/v1/{name=projects/*/zones/*/clusters/*/tables/*}" };
+  }
+
+  // Permanently deletes a specified table and all of its data.
+  rpc DeleteTable(DeleteTableRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { delete: "/v1/{name=projects/*/zones/*/clusters/*/tables/*}" };
+  }
+
+  // Changes the name of a specified table.
+  // Cannot be used to move tables between clusters, zones, or projects.
+  rpc RenameTable(RenameTableRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { post: "/v1/{name=projects/*/zones/*/clusters/*/tables/*}:rename" body: "*" };
+  }
+
+  // Creates a new column family within a specified table.
+  rpc CreateColumnFamily(CreateColumnFamilyRequest) returns (ColumnFamily) {
+    option (google.api.http) = { post: "/v1/{name=projects/*/zones/*/clusters/*/tables/*}/columnFamilies" body: "*" };
+  }
+
+  // Changes the configuration of a specified column family.
+  rpc UpdateColumnFamily(ColumnFamily) returns (ColumnFamily) {
+    option (google.api.http) = { put: "/v1/{name=projects/*/zones/*/clusters/*/tables/*/columnFamilies/*}" body: "*" };
+  }
+
+  // Permanently deletes a specified column family and all of its data.
+  rpc DeleteColumnFamily(DeleteColumnFamilyRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { delete: "/v1/{name=projects/*/zones/*/clusters/*/tables/*/columnFamilies/*}" };
+  }
+
+  // Delete all rows in a table corresponding to a particular prefix
+  rpc BulkDeleteRows(BulkDeleteRowsRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { post: "/v1/{table_name=projects/*/zones/*/clusters/*/tables/*}:bulkDeleteRows" body: "*" };
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_service_messages.proto b/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_service_messages.proto
new file mode 100644
index 000000000000..617ede65592f
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/bigtable_table_service_messages.proto
@@ -0,0 +1,116 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.admin.table.v1;
+
+import "google/bigtable/admin/table/v1/bigtable_table_data.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/table/v1;table";
+option java_multiple_files = true;
+option java_outer_classname = "BigtableTableServiceMessagesProto";
+option java_package = "com.google.bigtable.admin.table.v1";
+
+
+message CreateTableRequest {
+  // The unique name of the cluster in which to create the new table.
+  string name = 1;
+
+  // The name by which the new table should be referred to within the cluster,
+  // e.g. "foobar" rather than "<cluster_name>/tables/foobar".
+  string table_id = 2;
+
+  // The Table to create. The `name` field of the Table and all of its
+  // ColumnFamilies must be left blank, and will be populated in the response.
+  Table table = 3;
+
+  // The optional list of row keys that will be used to initially split the
+  // table into several tablets (Tablets are similar to HBase regions).
+  // Given two split keys, "s1" and "s2", three tablets will be created,
+  // spanning the key ranges: [, s1), [s1, s2), [s2, ).
+  //
+  // Example:
+  //  * Row keys := ["a", "apple", "custom", "customer_1", "customer_2",
+  //                 "other", "zz"]
+  //  * initial_split_keys := ["apple", "customer_1", "customer_2", "other"]
+  //  * Key assignment:
+  //    - Tablet 1 [, apple)                => {"a"}.
+  //    - Tablet 2 [apple, customer_1)      => {"apple", "custom"}.
+  //    - Tablet 3 [customer_1, customer_2) => {"customer_1"}.
+  //    - Tablet 4 [customer_2, other)      => {"customer_2"}.
+  //    - Tablet 5 [other, )                => {"other", "zz"}.
+  repeated string initial_split_keys = 4;
+}
+
+message ListTablesRequest {
+  // The unique name of the cluster for which tables should be listed.
+  string name = 1;
+}
+
+message ListTablesResponse {
+  // The tables present in the requested cluster.
+  // At present, only the names of the tables are populated.
+  repeated Table tables = 1;
+}
+
+message GetTableRequest {
+  // The unique name of the requested table.
+  string name = 1;
+}
+
+message DeleteTableRequest {
+  // The unique name of the table to be deleted.
+  string name = 1;
+}
+
+message RenameTableRequest {
+  // The current unique name of the table.
+  string name = 1;
+
+  // The new name by which the table should be referred to within its containing
+  // cluster, e.g. "foobar" rather than "<cluster_name>/tables/foobar".
+  string new_id = 2;
+}
+
+message CreateColumnFamilyRequest {
+  // The unique name of the table in which to create the new column family.
+  string name = 1;
+
+  // The name by which the new column family should be referred to within the
+  // table, e.g. "foobar" rather than "<table_name>/columnFamilies/foobar".
+  string column_family_id = 2;
+
+  // The column family to create. The `name` field must be left blank.
+  ColumnFamily column_family = 3;
+}
+
+message DeleteColumnFamilyRequest {
+  // The unique name of the column family to be deleted.
+  string name = 1;
+}
+
+message BulkDeleteRowsRequest {
+  // The unique name of the table on which to perform the bulk delete
+  string table_name = 1;
+
+  oneof target {
+    // Delete all rows that start with this row key prefix. Prefix cannot be
+    // zero length.
+    bytes row_key_prefix = 2;
+
+    // Delete all rows in the table. Setting this to false is a no-op.
+    bool delete_all_data_from_table = 3;
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/common.proto b/bigtable/google/cloud/bigtable_v2/proto/common.proto
new file mode 100644
index 000000000000..0ece12780eb9
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/common.proto
@@ -0,0 +1,41 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.bigtable.admin.v2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "CommonProto";
+option java_package = "com.google.bigtable.admin.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2";
+
+
+// Storage media types for persisting Bigtable data.
+enum StorageType {
+  // The user did not specify a storage type.
+  STORAGE_TYPE_UNSPECIFIED = 0;
+
+  // Flash (SSD) storage should be used.
+  SSD = 1;
+
+  // Magnetic drive (HDD) storage should be used.
+  HDD = 2;
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/data.proto b/bigtable/google/cloud/bigtable_v2/proto/data.proto
new file mode 100644
index 000000000000..7400197e7b17
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/data.proto
@@ -0,0 +1,535 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.v2;
+
+option csharp_namespace = "Google.Cloud.Bigtable.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/v2;bigtable";
+option java_multiple_files = true;
+option java_outer_classname = "DataProto";
+option java_package = "com.google.bigtable.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\V2";
+
+
+// Specifies the complete (requested) contents of a single row of a table.
+// Rows which exceed 256MiB in size cannot be read in full.
+message Row {
+  // The unique key which identifies this row within its table. This is the same
+  // key that's used to identify the row in, for example, a MutateRowRequest.
+  // May contain any non-empty byte string up to 4KiB in length.
+  bytes key = 1;
+
+  // May be empty, but only if the entire row is empty.
+  // The mutual ordering of column families is not specified.
+  repeated Family families = 2;
+}
+
+// Specifies (some of) the contents of a single row/column family intersection
+// of a table.
+message Family {
+  // The unique key which identifies this family within its row. This is the
+  // same key that's used to identify the family in, for example, a RowFilter
+  // which sets its "family_name_regex_filter" field.
+  // Must match `[-_.a-zA-Z0-9]+`, except that AggregatingRowProcessors may
+  // produce cells in a sentinel family with an empty name.
+  // Must be no greater than 64 characters in length.
+  string name = 1;
+
+  // Must not be empty. Sorted in order of increasing "qualifier".
+  repeated Column columns = 2;
+}
+
+// Specifies (some of) the contents of a single row/column intersection of a
+// table.
+message Column {
+  // The unique key which identifies this column within its family. This is the
+  // same key that's used to identify the column in, for example, a RowFilter
+  // which sets its `column_qualifier_regex_filter` field.
+  // May contain any byte string, including the empty string, up to 16kiB in
+  // length.
+  bytes qualifier = 1;
+
+  // Must not be empty. Sorted in order of decreasing "timestamp_micros".
+  repeated Cell cells = 2;
+}
+
+// Specifies (some of) the contents of a single row/column/timestamp of a table.
+message Cell {
+  // The cell's stored timestamp, which also uniquely identifies it within
+  // its column.
+  // Values are always expressed in microseconds, but individual tables may set
+  // a coarser granularity to further restrict the allowed values. For
+  // example, a table which specifies millisecond granularity will only allow
+  // values of `timestamp_micros` which are multiples of 1000.
+  int64 timestamp_micros = 1;
+
+  // The value stored in the cell.
+  // May contain any byte string, including the empty string, up to 100MiB in
+  // length.
+  bytes value = 2;
+
+  // Labels applied to the cell by a [RowFilter][google.bigtable.v2.RowFilter].
+  repeated string labels = 3;
+}
+
+// Specifies a contiguous range of rows.
+message RowRange {
+  // The row key at which to start the range.
+  // If neither field is set, interpreted as the empty string, inclusive.
+  oneof start_key {
+    // Used when giving an inclusive lower bound for the range.
+    bytes start_key_closed = 1;
+
+    // Used when giving an exclusive lower bound for the range.
+    bytes start_key_open = 2;
+  }
+
+  // The row key at which to end the range.
+  // If neither field is set, interpreted as the infinite row key, exclusive.
+  oneof end_key {
+    // Used when giving an exclusive upper bound for the range.
+    bytes end_key_open = 3;
+
+    // Used when giving an inclusive upper bound for the range.
+    bytes end_key_closed = 4;
+  }
+}
+
+// Specifies a non-contiguous set of rows.
+message RowSet {
+  // Single rows included in the set.
+  repeated bytes row_keys = 1;
+
+  // Contiguous row ranges included in the set.
+  repeated RowRange row_ranges = 2;
+}
+
+// Specifies a contiguous range of columns within a single column family.
+// The range spans from &lt;column_family&gt;:&lt;start_qualifier&gt; to
+// &lt;column_family&gt;:&lt;end_qualifier&gt;, where both bounds can be either
+// inclusive or exclusive.
+message ColumnRange {
+  // The name of the column family within which this range falls.
+  string family_name = 1;
+
+  // The column qualifier at which to start the range (within `column_family`).
+  // If neither field is set, interpreted as the empty string, inclusive.
+  oneof start_qualifier {
+    // Used when giving an inclusive lower bound for the range.
+    bytes start_qualifier_closed = 2;
+
+    // Used when giving an exclusive lower bound for the range.
+    bytes start_qualifier_open = 3;
+  }
+
+  // The column qualifier at which to end the range (within `column_family`).
+  // If neither field is set, interpreted as the infinite string, exclusive.
+  oneof end_qualifier {
+    // Used when giving an inclusive upper bound for the range.
+    bytes end_qualifier_closed = 4;
+
+    // Used when giving an exclusive upper bound for the range.
+    bytes end_qualifier_open = 5;
+  }
+}
+
+// Specified a contiguous range of microsecond timestamps.
+message TimestampRange {
+  // Inclusive lower bound. If left empty, interpreted as 0.
+  int64 start_timestamp_micros = 1;
+
+  // Exclusive upper bound. If left empty, interpreted as infinity.
+  int64 end_timestamp_micros = 2;
+}
+
+// Specifies a contiguous range of raw byte values.
+message ValueRange {
+  // The value at which to start the range.
+  // If neither field is set, interpreted as the empty string, inclusive.
+  oneof start_value {
+    // Used when giving an inclusive lower bound for the range.
+    bytes start_value_closed = 1;
+
+    // Used when giving an exclusive lower bound for the range.
+    bytes start_value_open = 2;
+  }
+
+  // The value at which to end the range.
+  // If neither field is set, interpreted as the infinite string, exclusive.
+  oneof end_value {
+    // Used when giving an inclusive upper bound for the range.
+    bytes end_value_closed = 3;
+
+    // Used when giving an exclusive upper bound for the range.
+    bytes end_value_open = 4;
+  }
+}
+
+// Takes a row as input and produces an alternate view of the row based on
+// specified rules. For example, a RowFilter might trim down a row to include
+// just the cells from columns matching a given regular expression, or might
+// return all the cells of a row but not their values. More complicated filters
+// can be composed out of these components to express requests such as, "within
+// every column of a particular family, give just the two most recent cells
+// which are older than timestamp X."
+//
+// There are two broad categories of RowFilters (true filters and transformers),
+// as well as two ways to compose simple filters into more complex ones
+// (chains and interleaves). They work as follows:
+//
+// * True filters alter the input row by excluding some of its cells wholesale
+// from the output row. An example of a true filter is the `value_regex_filter`,
+// which excludes cells whose values don't match the specified pattern. All
+// regex true filters use RE2 syntax (https://github.com/google/re2/wiki/Syntax)
+// in raw byte mode (RE2::Latin1), and are evaluated as full matches. An
+// important point to keep in mind is that `RE2(.)` is equivalent by default to
+// `RE2([^\n])`, meaning that it does not match newlines. When attempting to
+// match an arbitrary byte, you should therefore use the escape sequence `\C`,
+// which may need to be further escaped as `\\C` in your client language.
+//
+// * Transformers alter the input row by changing the values of some of its
+// cells in the output, without excluding them completely. Currently, the only
+// supported transformer is the `strip_value_transformer`, which replaces every
+// cell's value with the empty string.
+//
+// * Chains and interleaves are described in more detail in the
+// RowFilter.Chain and RowFilter.Interleave documentation.
+//
+// The total serialized size of a RowFilter message must not
+// exceed 4096 bytes, and RowFilters may not be nested within each other
+// (in Chains or Interleaves) to a depth of more than 20.
+message RowFilter {
+  // A RowFilter which sends rows through several RowFilters in sequence.
+  message Chain {
+    // The elements of "filters" are chained together to process the input row:
+    // in row -> f(0) -> intermediate row -> f(1) -> ... -> f(N) -> out row
+    // The full chain is executed atomically.
+    repeated RowFilter filters = 1;
+  }
+
+  // A RowFilter which sends each row to each of several component
+  // RowFilters and interleaves the results.
+  message Interleave {
+    // The elements of "filters" all process a copy of the input row, and the
+    // results are pooled, sorted, and combined into a single output row.
+    // If multiple cells are produced with the same column and timestamp,
+    // they will all appear in the output row in an unspecified mutual order.
+    // Consider the following example, with three filters:
+    //
+    //                                  input row
+    //                                      |
+    //            -----------------------------------------------------
+    //            |                         |                         |
+    //           f(0)                      f(1)                      f(2)
+    //            |                         |                         |
+    //     1: foo,bar,10,x             foo,bar,10,z              far,bar,7,a
+    //     2: foo,blah,11,z            far,blah,5,x              far,blah,5,x
+    //            |                         |                         |
+    //            -----------------------------------------------------
+    //                                      |
+    //     1:                      foo,bar,10,z   // could have switched with #2
+    //     2:                      foo,bar,10,x   // could have switched with #1
+    //     3:                      foo,blah,11,z
+    //     4:                      far,bar,7,a
+    //     5:                      far,blah,5,x   // identical to #6
+    //     6:                      far,blah,5,x   // identical to #5
+    //
+    // All interleaved filters are executed atomically.
+    repeated RowFilter filters = 1;
+  }
+
+  // A RowFilter which evaluates one of two possible RowFilters, depending on
+  // whether or not a predicate RowFilter outputs any cells from the input row.
+  //
+  // IMPORTANT NOTE: The predicate filter does not execute atomically with the
+  // true and false filters, which may lead to inconsistent or unexpected
+  // results. Additionally, Condition filters have poor performance, especially
+  // when filters are set for the false condition.
+  message Condition {
+    // If `predicate_filter` outputs any cells, then `true_filter` will be
+    // evaluated on the input row. Otherwise, `false_filter` will be evaluated.
+    RowFilter predicate_filter = 1;
+
+    // The filter to apply to the input row if `predicate_filter` returns any
+    // results. If not provided, no results will be returned in the true case.
+    RowFilter true_filter = 2;
+
+    // The filter to apply to the input row if `predicate_filter` does not
+    // return any results. If not provided, no results will be returned in the
+    // false case.
+    RowFilter false_filter = 3;
+  }
+
+  // Which of the possible RowFilter types to apply. If none are set, this
+  // RowFilter returns all cells in the input row.
+  oneof filter {
+    // Applies several RowFilters to the data in sequence, progressively
+    // narrowing the results.
+    Chain chain = 1;
+
+    // Applies several RowFilters to the data in parallel and combines the
+    // results.
+    Interleave interleave = 2;
+
+    // Applies one of two possible RowFilters to the data based on the output of
+    // a predicate RowFilter.
+    Condition condition = 3;
+
+    // ADVANCED USE ONLY.
+    // Hook for introspection into the RowFilter. Outputs all cells directly to
+    // the output of the read rather than to any parent filter. Consider the
+    // following example:
+    //
+    //     Chain(
+    //       FamilyRegex("A"),
+    //       Interleave(
+    //         All(),
+    //         Chain(Label("foo"), Sink())
+    //       ),
+    //       QualifierRegex("B")
+    //     )
+    //
+    //                         A,A,1,w
+    //                         A,B,2,x
+    //                         B,B,4,z
+    //                            |
+    //                     FamilyRegex("A")
+    //                            |
+    //                         A,A,1,w
+    //                         A,B,2,x
+    //                            |
+    //               +------------+-------------+
+    //               |                          |
+    //             All()                    Label(foo)
+    //               |                          |
+    //            A,A,1,w              A,A,1,w,labels:[foo]
+    //            A,B,2,x              A,B,2,x,labels:[foo]
+    //               |                          |
+    //               |                        Sink() --------------+
+    //               |                          |                  |
+    //               +------------+      x------+          A,A,1,w,labels:[foo]
+    //                            |                        A,B,2,x,labels:[foo]
+    //                         A,A,1,w                             |
+    //                         A,B,2,x                             |
+    //                            |                                |
+    //                    QualifierRegex("B")                      |
+    //                            |                                |
+    //                         A,B,2,x                             |
+    //                            |                                |
+    //                            +--------------------------------+
+    //                            |
+    //                         A,A,1,w,labels:[foo]
+    //                         A,B,2,x,labels:[foo]  // could be switched
+    //                         A,B,2,x               // could be switched
+    //
+    // Despite being excluded by the qualifier filter, a copy of every cell
+    // that reaches the sink is present in the final result.
+    //
+    // As with an [Interleave][google.bigtable.v2.RowFilter.Interleave],
+    // duplicate cells are possible, and appear in an unspecified mutual order.
+    // In this case we have a duplicate with column "A:B" and timestamp 2,
+    // because one copy passed through the all filter while the other was
+    // passed through the label and sink. Note that one copy has label "foo",
+    // while the other does not.
+    //
+    // Cannot be used within the `predicate_filter`, `true_filter`, or
+    // `false_filter` of a [Condition][google.bigtable.v2.RowFilter.Condition].
+    bool sink = 16;
+
+    // Matches all cells, regardless of input. Functionally equivalent to
+    // leaving `filter` unset, but included for completeness.
+    bool pass_all_filter = 17;
+
+    // Does not match any cells, regardless of input. Useful for temporarily
+    // disabling just part of a filter.
+    bool block_all_filter = 18;
+
+    // Matches only cells from rows whose keys satisfy the given RE2 regex. In
+    // other words, passes through the entire row when the key matches, and
+    // otherwise produces an empty row.
+    // Note that, since row keys can contain arbitrary bytes, the `\C` escape
+    // sequence must be used if a true wildcard is desired. The `.` character
+    // will not match the new line character `\n`, which may be present in a
+    // binary key.
+    bytes row_key_regex_filter = 4;
+
+    // Matches all cells from a row with probability p, and matches no cells
+    // from the row with probability 1-p.
+    double row_sample_filter = 14;
+
+    // Matches only cells from columns whose families satisfy the given RE2
+    // regex. For technical reasons, the regex must not contain the `:`
+    // character, even if it is not being used as a literal.
+    // Note that, since column families cannot contain the new line character
+    // `\n`, it is sufficient to use `.` as a full wildcard when matching
+    // column family names.
+    string family_name_regex_filter = 5;
+
+    // Matches only cells from columns whose qualifiers satisfy the given RE2
+    // regex.
+    // Note that, since column qualifiers can contain arbitrary bytes, the `\C`
+    // escape sequence must be used if a true wildcard is desired. The `.`
+    // character will not match the new line character `\n`, which may be
+    // present in a binary qualifier.
+    bytes column_qualifier_regex_filter = 6;
+
+    // Matches only cells from columns within the given range.
+    ColumnRange column_range_filter = 7;
+
+    // Matches only cells with timestamps within the given range.
+    TimestampRange timestamp_range_filter = 8;
+
+    // Matches only cells with values that satisfy the given regular expression.
+    // Note that, since cell values can contain arbitrary bytes, the `\C` escape
+    // sequence must be used if a true wildcard is desired. The `.` character
+    // will not match the new line character `\n`, which may be present in a
+    // binary value.
+    bytes value_regex_filter = 9;
+
+    // Matches only cells with values that fall within the given range.
+    ValueRange value_range_filter = 15;
+
+    // Skips the first N cells of each row, matching all subsequent cells.
+    // If duplicate cells are present, as is possible when using an Interleave,
+    // each copy of the cell is counted separately.
+    int32 cells_per_row_offset_filter = 10;
+
+    // Matches only the first N cells of each row.
+    // If duplicate cells are present, as is possible when using an Interleave,
+    // each copy of the cell is counted separately.
+    int32 cells_per_row_limit_filter = 11;
+
+    // Matches only the most recent N cells within each column. For example,
+    // if N=2, this filter would match column `foo:bar` at timestamps 10 and 9,
+    // skip all earlier cells in `foo:bar`, and then begin matching again in
+    // column `foo:bar2`.
+    // If duplicate cells are present, as is possible when using an Interleave,
+    // each copy of the cell is counted separately.
+    int32 cells_per_column_limit_filter = 12;
+
+    // Replaces each cell's value with the empty string.
+    bool strip_value_transformer = 13;
+
+    // Applies the given label to all cells in the output row. This allows
+    // the client to determine which results were produced from which part of
+    // the filter.
+    //
+    // Values must be at most 15 characters in length, and match the RE2
+    // pattern `[a-z0-9\\-]+`
+    //
+    // Due to a technical limitation, it is not currently possible to apply
+    // multiple labels to a cell. As a result, a Chain may have no more than
+    // one sub-filter which contains a `apply_label_transformer`. It is okay for
+    // an Interleave to contain multiple `apply_label_transformers`, as they
+    // will be applied to separate copies of the input. This may be relaxed in
+    // the future.
+    string apply_label_transformer = 19;
+  }
+}
+
+// Specifies a particular change to be made to the contents of a row.
+message Mutation {
+  // A Mutation which sets the value of the specified cell.
+  message SetCell {
+    // The name of the family into which new data should be written.
+    // Must match `[-_.a-zA-Z0-9]+`
+    string family_name = 1;
+
+    // The qualifier of the column into which new data should be written.
+    // Can be any byte string, including the empty string.
+    bytes column_qualifier = 2;
+
+    // The timestamp of the cell into which new data should be written.
+    // Use -1 for current Bigtable server time.
+    // Otherwise, the client should set this value itself, noting that the
+    // default value is a timestamp of zero if the field is left unspecified.
+    // Values must match the granularity of the table (e.g. micros, millis).
+    int64 timestamp_micros = 3;
+
+    // The value to be written into the specified cell.
+    bytes value = 4;
+  }
+
+  // A Mutation which deletes cells from the specified column, optionally
+  // restricting the deletions to a given timestamp range.
+  message DeleteFromColumn {
+    // The name of the family from which cells should be deleted.
+    // Must match `[-_.a-zA-Z0-9]+`
+    string family_name = 1;
+
+    // The qualifier of the column from which cells should be deleted.
+    // Can be any byte string, including the empty string.
+    bytes column_qualifier = 2;
+
+    // The range of timestamps within which cells should be deleted.
+    TimestampRange time_range = 3;
+  }
+
+  // A Mutation which deletes all cells from the specified column family.
+  message DeleteFromFamily {
+    // The name of the family from which cells should be deleted.
+    // Must match `[-_.a-zA-Z0-9]+`
+    string family_name = 1;
+  }
+
+  // A Mutation which deletes all cells from the containing row.
+  message DeleteFromRow {
+
+  }
+
+  // Which of the possible Mutation types to apply.
+  oneof mutation {
+    // Set a cell's value.
+    SetCell set_cell = 1;
+
+    // Deletes cells from a column.
+    DeleteFromColumn delete_from_column = 2;
+
+    // Deletes cells from a column family.
+    DeleteFromFamily delete_from_family = 3;
+
+    // Deletes cells from the entire row.
+    DeleteFromRow delete_from_row = 4;
+  }
+}
+
+// Specifies an atomic read/modify/write operation on the latest value of the
+// specified column.
+message ReadModifyWriteRule {
+  // The name of the family to which the read/modify/write should be applied.
+  // Must match `[-_.a-zA-Z0-9]+`
+  string family_name = 1;
+
+  // The qualifier of the column to which the read/modify/write should be
+  // applied.
+  // Can be any byte string, including the empty string.
+  bytes column_qualifier = 2;
+
+  // The rule used to determine the column's new latest value from its current
+  // latest value.
+  oneof rule {
+    // Rule specifying that `append_value` be appended to the existing value.
+    // If the targeted cell is unset, it will be treated as containing the
+    // empty string.
+    bytes append_value = 3;
+
+    // Rule specifying that `increment_amount` be added to the existing value.
+    // If the targeted cell is unset, it will be treated as containing a zero.
+    // Otherwise, the targeted cell must contain an 8-byte value (interpreted
+    // as a 64-bit big-endian signed integer), or the entire request will fail.
+    int64 increment_amount = 4;
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/instance.proto b/bigtable/google/cloud/bigtable_v2/proto/instance.proto
new file mode 100644
index 000000000000..bb69b1f66d42
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/instance.proto
@@ -0,0 +1,208 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.bigtable.admin.v2;
+
+import "google/api/annotations.proto";
+import "google/bigtable/admin/v2/common.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "InstanceProto";
+option java_package = "com.google.bigtable.admin.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2";
+
+
+// A collection of Bigtable [Tables][google.bigtable.admin.v2.Table] and
+// the resources that serve them.
+// All tables in an instance are served from a single
+// [Cluster][google.bigtable.admin.v2.Cluster].
+message Instance {
+  // Possible states of an instance.
+  enum State {
+    // The state of the instance could not be determined.
+    STATE_NOT_KNOWN = 0;
+
+    // The instance has been successfully created and can serve requests
+    // to its tables.
+    READY = 1;
+
+    // The instance is currently being created, and may be destroyed
+    // if the creation process encounters an error.
+    CREATING = 2;
+  }
+
+  // The type of the instance.
+  enum Type {
+    // The type of the instance is unspecified. If set when creating an
+    // instance, a `PRODUCTION` instance will be created. If set when updating
+    // an instance, the type will be left unchanged.
+    TYPE_UNSPECIFIED = 0;
+
+    // An instance meant for production use. `serve_nodes` must be set
+    // on the cluster.
+    PRODUCTION = 1;
+
+    // The instance is meant for development and testing purposes only; it has
+    // no performance or uptime guarantees and is not covered by SLA.
+    // After a development instance is created, it can be upgraded by
+    // updating the instance to type `PRODUCTION`. An instance created
+    // as a production instance cannot be changed to a development instance.
+    // When creating a development instance, `serve_nodes` on the cluster must
+    // not be set.
+    DEVELOPMENT = 2;
+  }
+
+  // (`OutputOnly`)
+  // The unique name of the instance. Values are of the form
+  // `projects/<project>/instances/[a-z][a-z0-9\\-]+[a-z0-9]`.
+  string name = 1;
+
+  // The descriptive name for this instance as it appears in UIs.
+  // Can be changed at any time, but should be kept globally unique
+  // to avoid confusion.
+  string display_name = 2;
+
+  // (`OutputOnly`)
+  // The current state of the instance.
+  State state = 3;
+
+  // The type of the instance. Defaults to `PRODUCTION`.
+  Type type = 4;
+
+  // Labels are a flexible and lightweight mechanism for organizing cloud
+  // resources into groups that reflect a customer's organizational needs and
+  // deployment strategies. They can be used to filter resources and aggregate
+  // metrics.
+  //
+  // * Label keys must be between 1 and 63 characters long and must conform to
+  //   the regular expression: `[\p{Ll}\p{Lo}][\p{Ll}\p{Lo}\p{N}_-]{0,62}`.
+  // * Label values must be between 0 and 63 characters long and must conform to
+  //   the regular expression: `[\p{Ll}\p{Lo}\p{N}_-]{0,63}`.
+  // * No more than 64 labels can be associated with a given resource.
+  // * Keys and values must both be under 128 bytes.
+  map<string, string> labels = 5;
+}
+
+// A resizable group of nodes in a particular cloud location, capable
+// of serving all [Tables][google.bigtable.admin.v2.Table] in the parent
+// [Instance][google.bigtable.admin.v2.Instance].
+message Cluster {
+  // Possible states of a cluster.
+  enum State {
+    // The state of the cluster could not be determined.
+    STATE_NOT_KNOWN = 0;
+
+    // The cluster has been successfully created and is ready to serve requests.
+    READY = 1;
+
+    // The cluster is currently being created, and may be destroyed
+    // if the creation process encounters an error.
+    // A cluster may not be able to serve requests while being created.
+    CREATING = 2;
+
+    // The cluster is currently being resized, and may revert to its previous
+    // node count if the process encounters an error.
+    // A cluster is still capable of serving requests while being resized,
+    // but may exhibit performance as if its number of allocated nodes is
+    // between the starting and requested states.
+    RESIZING = 3;
+
+    // The cluster has no backing nodes. The data (tables) still
+    // exist, but no operations can be performed on the cluster.
+    DISABLED = 4;
+  }
+
+  // (`OutputOnly`)
+  // The unique name of the cluster. Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/[a-z][-a-z0-9]*`.
+  string name = 1;
+
+  // (`CreationOnly`)
+  // The location where this cluster's nodes and storage reside. For best
+  // performance, clients should be located as close as possible to this
+  // cluster. Currently only zones are supported, so values should be of the
+  // form `projects/<project>/locations/<zone>`.
+  string location = 2;
+
+  // (`OutputOnly`)
+  // The current state of the cluster.
+  State state = 3;
+
+  // The number of nodes allocated to this cluster. More nodes enable higher
+  // throughput and more consistent performance.
+  int32 serve_nodes = 4;
+
+  // (`CreationOnly`)
+  // The type of storage used by this cluster to serve its
+  // parent instance's tables, unless explicitly overridden.
+  StorageType default_storage_type = 5;
+}
+
+// A configuration object describing how Cloud Bigtable should treat traffic
+// from a particular end user application.
+message AppProfile {
+  // Read/write requests may be routed to any cluster in the instance, and will
+  // fail over to another cluster in the event of transient errors or delays.
+  // Choosing this option sacrifices read-your-writes consistency to improve
+  // availability.
+  message MultiClusterRoutingUseAny {
+
+  }
+
+  // Unconditionally routes all read/write requests to a specific cluster.
+  // This option preserves read-your-writes consistency, but does not improve
+  // availability.
+  message SingleClusterRouting {
+    // The cluster to which read/write requests should be routed.
+    string cluster_id = 1;
+
+    // Whether or not `CheckAndMutateRow` and `ReadModifyWriteRow` requests are
+    // allowed by this app profile. It is unsafe to send these requests to
+    // the same table/row/column in multiple clusters.
+    bool allow_transactional_writes = 2;
+  }
+
+  // (`OutputOnly`)
+  // The unique name of the app profile. Values are of the form
+  // `projects/<project>/instances/<instance>/appProfiles/[_a-zA-Z0-9][-_.a-zA-Z0-9]*`.
+  string name = 1;
+
+  // Strongly validated etag for optimistic concurrency control. Preserve the
+  // value returned from `GetAppProfile` when calling `UpdateAppProfile` to
+  // fail the request if there has been a modification in the mean time. The
+  // `update_mask` of the request need not include `etag` for this protection
+  // to apply.
+  // See [Wikipedia](https://en.wikipedia.org/wiki/HTTP_ETag) and
+  // [RFC 7232](https://tools.ietf.org/html/rfc7232#section-2.3) for more
+  // details.
+  string etag = 2;
+
+  // Optional long form description of the use case for this AppProfile.
+  string description = 3;
+
+  // The routing policy for all read/write requests which use this app profile.
+  // A value must be explicitly set.
+  oneof routing_policy {
+    // Use a multi-cluster routing policy that may pick any cluster.
+    MultiClusterRoutingUseAny multi_cluster_routing_use_any = 5;
+
+    // Use a single-cluster routing policy.
+    SingleClusterRouting single_cluster_routing = 6;
+  }
+}
diff --git a/bigtable/google/cloud/bigtable_v2/proto/table.proto b/bigtable/google/cloud/bigtable_v2/proto/table.proto
new file mode 100644
index 000000000000..5d4374effc59
--- /dev/null
+++ b/bigtable/google/cloud/bigtable_v2/proto/table.proto
@@ -0,0 +1,221 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.bigtable.admin.v2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2";
+option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "TableProto";
+option java_package = "com.google.bigtable.admin.v2";
+option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2";
+
+
+// A collection of user data indexed by row, column, and timestamp.
+// Each table is served using the resources of its parent cluster.
+message Table {
+  // The state of a table's data in a particular cluster.
+  message ClusterState {
+    // Table replication states.
+    enum ReplicationState {
+      // The replication state of the table is unknown in this cluster.
+      STATE_NOT_KNOWN = 0;
+
+      // The cluster was recently created, and the table must finish copying
+      // over pre-existing data from other clusters before it can begin
+      // receiving live replication updates and serving Data API requests.
+      INITIALIZING = 1;
+
+      // The table is temporarily unable to serve Data API requests from this
+      // cluster due to planned internal maintenance.
+      PLANNED_MAINTENANCE = 2;
+
+      // The table is temporarily unable to serve Data API requests from this
+      // cluster due to unplanned or emergency maintenance.
+      UNPLANNED_MAINTENANCE = 3;
+
+      // The table can serve Data API requests from this cluster. Depending on
+      // replication delay, reads may not immediately reflect the state of the
+      // table in other clusters.
+      READY = 4;
+    }
+
+    // (`OutputOnly`)
+    // The state of replication for the table in this cluster.
+    ReplicationState replication_state = 1;
+  }
+
+  // Possible timestamp granularities to use when keeping multiple versions
+  // of data in a table.
+  enum TimestampGranularity {
+    // The user did not specify a granularity. Should not be returned.
+    // When specified during table creation, MILLIS will be used.
+    TIMESTAMP_GRANULARITY_UNSPECIFIED = 0;
+
+    // The table keeps data versioned at a granularity of 1ms.
+    MILLIS = 1;
+  }
+
+  // Defines a view over a table's fields.
+  enum View {
+    // Uses the default view for each method as documented in its request.
+    VIEW_UNSPECIFIED = 0;
+
+    // Only populates `name`.
+    NAME_ONLY = 1;
+
+    // Only populates `name` and fields related to the table's schema.
+    SCHEMA_VIEW = 2;
+
+    // Only populates `name` and fields related to the table's
+    // replication state.
+    REPLICATION_VIEW = 3;
+
+    // Populates all fields.
+    FULL = 4;
+  }
+
+  // (`OutputOnly`)
+  // The unique name of the table. Values are of the form
+  // `projects/<project>/instances/<instance>/tables/[_a-zA-Z0-9][-_.a-zA-Z0-9]*`.
+  // Views: `NAME_ONLY`, `SCHEMA_VIEW`, `REPLICATION_VIEW`, `FULL`
+  string name = 1;
+
+  // (`OutputOnly`)
+  // Map from cluster ID to per-cluster table state.
+  // If it could not be determined whether or not the table has data in a
+  // particular cluster (for example, if its zone is unavailable), then
+  // there will be an entry for the cluster with UNKNOWN `replication_status`.
+  // Views: `REPLICATION_VIEW`, `FULL`
+  map<string, ClusterState> cluster_states = 2;
+
+  // (`CreationOnly`)
+  // The column families configured for this table, mapped by column family ID.
+  // Views: `SCHEMA_VIEW`, `FULL`
+  map<string, ColumnFamily> column_families = 3;
+
+  // (`CreationOnly`)
+  // The granularity (i.e. `MILLIS`) at which timestamps are stored in
+  // this table. Timestamps not matching the granularity will be rejected.
+  // If unspecified at creation time, the value will be set to `MILLIS`.
+  // Views: `SCHEMA_VIEW`, `FULL`
+  TimestampGranularity granularity = 4;
+}
+
+// A set of columns within a table which share a common configuration.
+message ColumnFamily {
+  // Garbage collection rule specified as a protobuf.
+  // Must serialize to at most 500 bytes.
+  //
+  // NOTE: Garbage collection executes opportunistically in the background, and
+  // so it's possible for reads to return a cell even if it matches the active
+  // GC expression for its family.
+  GcRule gc_rule = 1;
+}
+
+// Rule for determining which cells to delete during garbage collection.
+message GcRule {
+  // A GcRule which deletes cells matching all of the given rules.
+  message Intersection {
+    // Only delete cells which would be deleted by every element of `rules`.
+    repeated GcRule rules = 1;
+  }
+
+  // A GcRule which deletes cells matching any of the given rules.
+  message Union {
+    // Delete cells which would be deleted by any element of `rules`.
+    repeated GcRule rules = 1;
+  }
+
+  // Garbage collection rules.
+  oneof rule {
+    // Delete all cells in a column except the most recent N.
+    int32 max_num_versions = 1;
+
+    // Delete cells in a column older than the given age.
+    // Values must be at least one millisecond, and will be truncated to
+    // microsecond granularity.
+    google.protobuf.Duration max_age = 2;
+
+    // Delete cells that would be deleted by every nested rule.
+    Intersection intersection = 3;
+
+    // Delete cells that would be deleted by any nested rule.
+    Union union = 4;
+  }
+}
+
+// A snapshot of a table at a particular time. A snapshot can be used as a
+// checkpoint for data restoration or a data source for a new table.
+//
+// Note: This is a private alpha release of Cloud Bigtable snapshots. This
+// feature is not currently available to most Cloud Bigtable customers. This
+// feature might be changed in backward-incompatible ways and is not recommended
+// for production use. It is not subject to any SLA or deprecation policy.
+message Snapshot {
+  // Possible states of a snapshot.
+  enum State {
+    // The state of the snapshot could not be determined.
+    STATE_NOT_KNOWN = 0;
+
+    // The snapshot has been successfully created and can serve all requests.
+    READY = 1;
+
+    // The snapshot is currently being created, and may be destroyed if the
+    // creation process encounters an error. A snapshot may not be restored to a
+    // table while it is being created.
+    CREATING = 2;
+  }
+
+  // (`OutputOnly`)
+  // The unique name of the snapshot.
+  // Values are of the form
+  // `projects/<project>/instances/<instance>/clusters/<cluster>/snapshots/<snapshot>`.
+  string name = 1;
+
+  // (`OutputOnly`)
+  // The source table at the time the snapshot was taken.
+  Table source_table = 2;
+
+  // (`OutputOnly`)
+  // The size of the data in the source table at the time the snapshot was
+  // taken. In some cases, this value may be computed asynchronously via a
+  // background process and a placeholder of 0 will be used in the meantime.
+  int64 data_size_bytes = 3;
+
+  // (`OutputOnly`)
+  // The time when the snapshot is created.
+  google.protobuf.Timestamp create_time = 4;
+
+  // (`OutputOnly`)
+  // The time when the snapshot will be deleted. The maximum amount of time a
+  // snapshot can stay active is 365 days. If 'ttl' is not specified,
+  // the default maximum of 365 days will be used.
+  google.protobuf.Timestamp delete_time = 5;
+
+  // (`OutputOnly`)
+  // The current state of the snapshot.
+  State state = 6;
+
+  // (`OutputOnly`)
+  // Description of the snapshot.
+  string description = 7;
+}
diff --git a/bigtable/synth.metadata b/bigtable/synth.metadata
index 034dbbb17183..9c5555a83895 100644
--- a/bigtable/synth.metadata
+++ b/bigtable/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:14:02.679846Z",
+  "updateTime": "2019-01-23T22:43:21.170639Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/bigtable/synth.py b/bigtable/synth.py
index f1bec2c6a8e2..edffa43640dd 100644
--- a/bigtable/synth.py
+++ b/bigtable/synth.py
@@ -28,6 +28,7 @@
     "v2",
     config_path="/google/bigtable/artman_bigtable.yaml",
     artman_output_name="bigtable-v2",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/bigtable_v2")
@@ -39,6 +40,7 @@
     "v2",
     config_path="/google/bigtable/admin/artman_bigtableadmin.yaml",
     artman_output_name="bigtable-admin-v2",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/bigtable_admin_v2")
diff --git a/container/google/cloud/container_v1/proto/cluster_service.proto b/container/google/cloud/container_v1/proto/cluster_service.proto
new file mode 100644
index 000000000000..46c91445fbac
--- /dev/null
+++ b/container/google/cloud/container_v1/proto/cluster_service.proto
@@ -0,0 +1,1934 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.container.v1alpha1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/container/v1alpha1;container";
+option java_multiple_files = true;
+option java_outer_classname = "ClusterServiceProto";
+option java_package = "com.google.container.v1alpha1";
+option csharp_namespace = "Google.Cloud.Container.V1Alpha1";
+option php_namespace = "Google\\Cloud\\Container\\V1alpha1";
+
+
+// Google Container Engine Cluster Manager v1alpha1
+service ClusterManager {
+  // Lists all clusters owned by a project in either the specified zone or all
+  // zones.
+  rpc ListClusters(ListClustersRequest) returns (ListClustersResponse) {
+    option (google.api.http) = { get: "/v1alpha1/{parent=projects/*/locations/*}/clusters" };
+  }
+
+  // Gets the details of a specific cluster.
+  rpc GetCluster(GetClusterRequest) returns (Cluster) {
+    option (google.api.http) = { get: "/v1alpha1/{name=projects/*/locations/*/clusters/*}" };
+  }
+
+  // Creates a cluster, consisting of the specified number and type of Google
+  // Compute Engine instances.
+  //
+  // By default, the cluster is created in the project's
+  // [default network](/compute/docs/networks-and-firewalls#networks).
+  //
+  // One firewall is added for the cluster. After cluster creation,
+  // the cluster creates routes for each node to allow the containers
+  // on that node to communicate with all other instances in the
+  // cluster.
+  //
+  // Finally, an entry is added to the project's global metadata indicating
+  // which CIDR range is being used by the cluster.
+  rpc CreateCluster(CreateClusterRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{parent=projects/*/locations/*}/clusters" body: "*" };
+  }
+
+  // Updates the settings of a specific cluster.
+  rpc UpdateCluster(UpdateClusterRequest) returns (Operation) {
+    option (google.api.http) = { put: "/v1alpha1/{name=projects/*/locations/*/clusters/*}" body: "*" };
+  }
+
+  // Updates the version and/or iamge type of a specific node pool.
+  rpc UpdateNodePool(UpdateNodePoolRequest) returns (Operation) {
+    option (google.api.http) = { put: "/v1alpha1/{name=projects/*/locations/*/clusters/*/nodePools/*}" body: "*" };
+  }
+
+  // Sets the autoscaling settings of a specific node pool.
+  rpc SetNodePoolAutoscaling(SetNodePoolAutoscalingRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*/nodePools/*}:setAutoscaling" body: "*" };
+  }
+
+  // Sets the logging service of a specific cluster.
+  rpc SetLoggingService(SetLoggingServiceRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:setLogging" body: "*" };
+  }
+
+  // Sets the monitoring service of a specific cluster.
+  rpc SetMonitoringService(SetMonitoringServiceRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:setMonitoring" body: "*" };
+  }
+
+  // Sets the addons of a specific cluster.
+  rpc SetAddonsConfig(SetAddonsConfigRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:setAddons" body: "*" };
+  }
+
+  // Sets the locations of a specific cluster.
+  rpc SetLocations(SetLocationsRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:setLocations" body: "*" };
+  }
+
+  // Updates the master of a specific cluster.
+  rpc UpdateMaster(UpdateMasterRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:updateMaster" body: "*" };
+  }
+
+  // Used to set master auth materials. Currently supports :-
+  // Changing the admin password of a specific cluster.
+  // This can be either via password generation or explicitly set.
+  // Modify basic_auth.csv and reset the K8S API server.
+  rpc SetMasterAuth(SetMasterAuthRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:setMasterAuth" body: "*" };
+  }
+
+  // Deletes the cluster, including the Kubernetes endpoint and all worker
+  // nodes.
+  //
+  // Firewalls and routes that were configured during cluster creation
+  // are also deleted.
+  //
+  // Other Google Compute Engine resources that might be in use by the cluster
+  // (e.g. load balancer resources) will not be deleted if they weren't present
+  // at the initial create time.
+  rpc DeleteCluster(DeleteClusterRequest) returns (Operation) {
+    option (google.api.http) = { delete: "/v1alpha1/{name=projects/*/locations/*/clusters/*}" };
+  }
+
+  // Lists all operations in a project in a specific zone or all zones.
+  rpc ListOperations(ListOperationsRequest) returns (ListOperationsResponse) {
+    option (google.api.http) = { get: "/v1alpha1/{parent=projects/*/locations/*}/operations" };
+  }
+
+  // Gets the specified operation.
+  rpc GetOperation(GetOperationRequest) returns (Operation) {
+    option (google.api.http) = { get: "/v1alpha1/{name=projects/*/locations/*/operations/*}" };
+  }
+
+  // Cancels the specified operation.
+  rpc CancelOperation(CancelOperationRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/operations/*}:cancel" body: "*" };
+  }
+
+  // Returns configuration info about the Container Engine service.
+  rpc GetServerConfig(GetServerConfigRequest) returns (ServerConfig) {
+    option (google.api.http) = { get: "/v1alpha1/{name=projects/*/locations/*}/serverConfig" };
+  }
+
+  // Lists the node pools for a cluster.
+  rpc ListNodePools(ListNodePoolsRequest) returns (ListNodePoolsResponse) {
+    option (google.api.http) = { get: "/v1alpha1/{parent=projects/*/locations/*/clusters/*}/nodePools" };
+  }
+
+  // Retrieves the node pool requested.
+  rpc GetNodePool(GetNodePoolRequest) returns (NodePool) {
+    option (google.api.http) = { get: "/v1alpha1/{name=projects/*/locations/*/clusters/*/nodePools/*}" };
+  }
+
+  // Creates a node pool for a cluster.
+  rpc CreateNodePool(CreateNodePoolRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{parent=projects/*/locations/*/clusters/*}/nodePools" body: "*" };
+  }
+
+  // Deletes a node pool from a cluster.
+  rpc DeleteNodePool(DeleteNodePoolRequest) returns (Operation) {
+    option (google.api.http) = { delete: "/v1alpha1/{name=projects/*/locations/*/clusters/*/nodePools/*}" };
+  }
+
+  // Roll back the previously Aborted or Failed NodePool upgrade.
+  // This will be an no-op if the last upgrade successfully completed.
+  rpc RollbackNodePoolUpgrade(RollbackNodePoolUpgradeRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*/nodePools/*}:rollback" body: "*" };
+  }
+
+  // Sets the NodeManagement options for a node pool.
+  rpc SetNodePoolManagement(SetNodePoolManagementRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*/nodePools/*}:setManagement" body: "*" };
+  }
+
+  // Sets labels on a cluster.
+  rpc SetLabels(SetLabelsRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:setResourceLabels" body: "*" };
+  }
+
+  // Enables or disables the ABAC authorization mechanism on a cluster.
+  rpc SetLegacyAbac(SetLegacyAbacRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:setLegacyAbac" body: "*" };
+  }
+
+  // Start master IP rotation.
+  rpc StartIPRotation(StartIPRotationRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:startIpRotation" body: "*" };
+  }
+
+  // Completes master IP rotation.
+  rpc CompleteIPRotation(CompleteIPRotationRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:completeIpRotation" body: "*" };
+  }
+
+  // Sets the size of a specific node pool.
+  rpc SetNodePoolSize(SetNodePoolSizeRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*/nodePools/*}:setSize" body: "*" };
+  }
+
+  // Enables/Disables Network Policy for a cluster.
+  rpc SetNetworkPolicy(SetNetworkPolicyRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:setNetworkPolicy" body: "*" };
+  }
+
+  // Sets the maintenance policy for a cluster.
+  rpc SetMaintenancePolicy(SetMaintenancePolicyRequest) returns (Operation) {
+    option (google.api.http) = { post: "/v1alpha1/{name=projects/*/locations/*/clusters/*}:setMaintenancePolicy" body: "*" };
+  }
+}
+
+// Parameters that describe the nodes in a cluster.
+message NodeConfig {
+  // The name of a Google Compute Engine [machine
+  // type](/compute/docs/machine-types) (e.g.
+  // `n1-standard-1`).
+  //
+  // If unspecified, the default machine type is
+  // `n1-standard-1`.
+  string machine_type = 1;
+
+  // Size of the disk attached to each node, specified in GB.
+  // The smallest allowed disk size is 10GB.
+  //
+  // If unspecified, the default disk size is 100GB.
+  int32 disk_size_gb = 2;
+
+  // The set of Google API scopes to be made available on all of the
+  // node VMs under the "default" service account.
+  //
+  // The following scopes are recommended, but not required, and by default are
+  // not included:
+  //
+  // * `https://www.googleapis.com/auth/compute` is required for mounting
+  // persistent storage on your nodes.
+  // * `https://www.googleapis.com/auth/devstorage.read_only` is required for
+  // communicating with **gcr.io**
+  // (the [Google Container Registry](/container-registry/)).
+  //
+  // If unspecified, no scopes are added, unless Cloud Logging or Cloud
+  // Monitoring are enabled, in which case their required scopes will be added.
+  repeated string oauth_scopes = 3;
+
+  // The Google Cloud Platform Service Account to be used by the node VMs. If
+  // no Service Account is specified, the "default" service account is used.
+  string service_account = 9;
+
+  // The metadata key/value pairs assigned to instances in the cluster.
+  //
+  // Keys must conform to the regexp [a-zA-Z0-9-_]+ and be less than 128 bytes
+  // in length. These are reflected as part of a URL in the metadata server.
+  // Additionally, to avoid ambiguity, keys must not conflict with any other
+  // metadata keys for the project or be one of the four reserved keys:
+  // "instance-template", "kube-env", "startup-script", and "user-data"
+  //
+  // Values are free-form strings, and only have meaning as interpreted by
+  // the image running in the instance. The only restriction placed on them is
+  // that each value's size must be less than or equal to 32 KB.
+  //
+  // The total size of all keys and values must be less than 512 KB.
+  map<string, string> metadata = 4;
+
+  // The image type to use for this node. Note that for a given image type,
+  // the latest version of it will be used.
+  string image_type = 5;
+
+  // The map of Kubernetes labels (key/value pairs) to be applied to each node.
+  // These will added in addition to any default label(s) that
+  // Kubernetes may apply to the node.
+  // In case of conflict in label keys, the applied set may differ depending on
+  // the Kubernetes version -- it's best to assume the behavior is undefined
+  // and conflicts should be avoided.
+  // For more information, including usage and the valid values, see:
+  // https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
+  map<string, string> labels = 6;
+
+  // The number of local SSD disks to be attached to the node.
+  //
+  // The limit for this value is dependant upon the maximum number of
+  // disks available on a machine per zone. See:
+  // https://cloud.google.com/compute/docs/disks/local-ssd#local_ssd_limits
+  // for more information.
+  int32 local_ssd_count = 7;
+
+  // The list of instance tags applied to all nodes. Tags are used to identify
+  // valid sources or targets for network firewalls and are specified by
+  // the client during cluster or node pool creation. Each tag within the list
+  // must comply with RFC1035.
+  repeated string tags = 8;
+
+  // Whether the nodes are created as preemptible VM instances. See:
+  // https://cloud.google.com/compute/docs/instances/preemptible for more
+  // inforamtion about preemptible VM instances.
+  bool preemptible = 10;
+
+  // A list of hardware accelerators to be attached to each node.
+  // See https://cloud.google.com/compute/docs/gpus for more information about
+  // support for GPUs.
+  repeated AcceleratorConfig accelerators = 11;
+
+  // Minimum CPU platform to be used by this instance. The instance may be
+  // scheduled on the specified or newer CPU platform. Applicable values are the
+  // friendly names of CPU platforms, such as
+  // <code>minCpuPlatform: &quot;Intel Haswell&quot;</code> or
+  // <code>minCpuPlatform: &quot;Intel Sandy Bridge&quot;</code>. For more
+  // information, read [how to specify min CPU platform](https://cloud.google.com/compute/docs/instances/specify-min-cpu-platform)
+  string min_cpu_platform = 13;
+
+  // List of kubernetes taints to be applied to each node.
+  //
+  // For more information, including usage and the valid values, see:
+  // https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
+  repeated NodeTaint taints = 15;
+}
+
+// Kubernetes taint is comprised of three fields: key, value, and effect. Effect
+// can only be one of three types:  NoSchedule, PreferNoSchedule or NoExecute.
+//
+// For more information, including usage and the valid values, see:
+// https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
+message NodeTaint {
+  // Possible values for Effect in taint.
+  enum Effect {
+    // Not set
+    EFFECT_UNSPECIFIED = 0;
+
+    // NoSchedule
+    NO_SCHEDULE = 1;
+
+    // PreferNoSchedule
+    PREFER_NO_SCHEDULE = 2;
+
+    // NoExecute
+    NO_EXECUTE = 3;
+  }
+
+  // Key for taint.
+  string key = 1;
+
+  // Value for taint.
+  string value = 2;
+
+  // Effect for taint.
+  Effect effect = 3;
+}
+
+// The authentication information for accessing the master endpoint.
+// Authentication can be done using HTTP basic auth or using client
+// certificates.
+message MasterAuth {
+  // The username to use for HTTP basic authentication to the master endpoint.
+  // For clusters v1.6.0 and later, you can disable basic authentication by
+  // providing an empty username.
+  string username = 1;
+
+  // The password to use for HTTP basic authentication to the master endpoint.
+  // Because the master endpoint is open to the Internet, you should create a
+  // strong password.  If a password is provided for cluster creation, username
+  // must be non-empty.
+  string password = 2;
+
+  // Configuration for client certificate authentication on the cluster.  If no
+  // configuration is specified, a client certificate is issued.
+  ClientCertificateConfig client_certificate_config = 3;
+
+  // [Output only] Base64-encoded public certificate that is the root of
+  // trust for the cluster.
+  string cluster_ca_certificate = 100;
+
+  // [Output only] Base64-encoded public certificate used by clients to
+  // authenticate to the cluster endpoint.
+  string client_certificate = 101;
+
+  // [Output only] Base64-encoded private key used by clients to authenticate
+  // to the cluster endpoint.
+  string client_key = 102;
+}
+
+// Configuration for client certificates on the cluster.
+message ClientCertificateConfig {
+  // Issue a client certificate.
+  bool issue_client_certificate = 1;
+}
+
+// Configuration for the addons that can be automatically spun up in the
+// cluster, enabling additional functionality.
+message AddonsConfig {
+  // Configuration for the HTTP (L7) load balancing controller addon, which
+  // makes it easy to set up HTTP load balancers for services in a cluster.
+  HttpLoadBalancing http_load_balancing = 1;
+
+  // Configuration for the horizontal pod autoscaling feature, which
+  // increases or decreases the number of replica pods a replication controller
+  // has based on the resource usage of the existing pods.
+  HorizontalPodAutoscaling horizontal_pod_autoscaling = 2;
+
+  // Configuration for the Kubernetes Dashboard.
+  KubernetesDashboard kubernetes_dashboard = 3;
+
+  // Configuration for NetworkPolicy. This only tracks whether the addon
+  // is enabled or not on the Master, it does not track whether network policy
+  // is enabled for the nodes.
+  NetworkPolicyConfig network_policy_config = 4;
+}
+
+// Configuration options for the HTTP (L7) load balancing controller addon,
+// which makes it easy to set up HTTP load balancers for services in a cluster.
+message HttpLoadBalancing {
+  // Whether the HTTP Load Balancing controller is enabled in the cluster.
+  // When enabled, it runs a small pod in the cluster that manages the load
+  // balancers.
+  bool disabled = 1;
+}
+
+// Configuration options for the horizontal pod autoscaling feature, which
+// increases or decreases the number of replica pods a replication controller
+// has based on the resource usage of the existing pods.
+message HorizontalPodAutoscaling {
+  // Whether the Horizontal Pod Autoscaling feature is enabled in the cluster.
+  // When enabled, it ensures that a Heapster pod is running in the cluster,
+  // which is also used by the Cloud Monitoring service.
+  bool disabled = 1;
+}
+
+// Configuration for the Kubernetes Dashboard.
+message KubernetesDashboard {
+  // Whether the Kubernetes Dashboard is enabled for this cluster.
+  bool disabled = 1;
+}
+
+// Configuration for NetworkPolicy. This only tracks whether the addon
+// is enabled or not on the Master, it does not track whether network policy
+// is enabled for the nodes.
+message NetworkPolicyConfig {
+  // Whether NetworkPolicy is enabled for this cluster.
+  bool disabled = 1;
+}
+
+// Configuration options for the master authorized networks feature. Enabled
+// master authorized networks will disallow all external traffic to access
+// Kubernetes master through HTTPS except traffic from the given CIDR blocks,
+// Google Compute Engine Public IPs and Google Prod IPs.
+message MasterAuthorizedNetworksConfig {
+  // CidrBlock contains an optional name and one CIDR block.
+  message CidrBlock {
+    // display_name is an optional field for users to identify CIDR blocks.
+    string display_name = 1;
+
+    // cidr_block must be specified in CIDR notation.
+    string cidr_block = 2;
+  }
+
+  // Whether or not master authorized networks is enabled.
+  bool enabled = 1;
+
+  // cidr_blocks define up to 10 external networks that could access
+  // Kubernetes master through HTTPS.
+  repeated CidrBlock cidr_blocks = 2;
+}
+
+// Configuration options for the NetworkPolicy feature.
+// https://kubernetes.io/docs/concepts/services-networking/networkpolicies/
+message NetworkPolicy {
+  // Allowed Network Policy providers.
+  enum Provider {
+    // Not set
+    PROVIDER_UNSPECIFIED = 0;
+
+    // Tigera (Calico Felix).
+    CALICO = 1;
+  }
+
+  // The selected network policy provider.
+  Provider provider = 1;
+
+  // Whether network policy is enabled on the cluster.
+  bool enabled = 2;
+}
+
+// Configuration for controlling how IPs are allocated in the cluster.
+message IPAllocationPolicy {
+  // Whether alias IPs will be used for pod IPs in the cluster.
+  bool use_ip_aliases = 1;
+
+  // Whether a new subnetwork will be created automatically for the cluster.
+  //
+  // This field is only applicable when `use_ip_aliases` is true.
+  bool create_subnetwork = 2;
+
+  // A custom subnetwork name to be used if `create_subnetwork` is true.  If
+  // this field is empty, then an automatic name will be chosen for the new
+  // subnetwork.
+  string subnetwork_name = 3;
+
+  // This field is deprecated, use cluster_ipv4_cidr_block.
+  string cluster_ipv4_cidr = 4;
+
+  // This field is deprecated, use node_ipv4_cidr_block.
+  string node_ipv4_cidr = 5;
+
+  // This field is deprecated, use services_ipv4_cidr_block.
+  string services_ipv4_cidr = 6;
+
+  // The name of the secondary range to be used for the cluster CIDR
+  // block.  The secondary range will be used for pod IP
+  // addresses. This must be an existing secondary range associated
+  // with the cluster subnetwork.
+  //
+  // This field is only applicable if use_ip_aliases is true and
+  // create_subnetwork is false.
+  string cluster_secondary_range_name = 7;
+
+  // The name of the secondary range to be used as for the services
+  // CIDR block.  The secondary range will be used for service
+  // ClusterIPs. This must be an existing secondary range associated
+  // with the cluster subnetwork.
+  //
+  // This field is only applicable with use_ip_aliases is true and
+  // create_subnetwork is false.
+  string services_secondary_range_name = 8;
+
+  // The IP address range for the cluster pod IPs. If this field is set, then
+  // `cluster.cluster_ipv4_cidr` must be left blank.
+  //
+  // This field is only applicable when `use_ip_aliases` is true.
+  //
+  // Set to blank to have a range chosen with the default size.
+  //
+  // Set to /netmask (e.g. `/14`) to have a range chosen with a specific
+  // netmask.
+  //
+  // Set to a
+  // [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing)
+  // notation (e.g. `10.96.0.0/14`) from the RFC-1918 private networks (e.g.
+  // `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) to pick a specific range
+  // to use.
+  string cluster_ipv4_cidr_block = 9;
+
+  // The IP address range of the instance IPs in this cluster.
+  //
+  // This is applicable only if `create_subnetwork` is true.
+  //
+  // Set to blank to have a range chosen with the default size.
+  //
+  // Set to /netmask (e.g. `/14`) to have a range chosen with a specific
+  // netmask.
+  //
+  // Set to a
+  // [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing)
+  // notation (e.g. `10.96.0.0/14`) from the RFC-1918 private networks (e.g.
+  // `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) to pick a specific range
+  // to use.
+  string node_ipv4_cidr_block = 10;
+
+  // The IP address range of the services IPs in this cluster. If blank, a range
+  // will be automatically chosen with the default size.
+  //
+  // This field is only applicable when `use_ip_aliases` is true.
+  //
+  // Set to blank to have a range chosen with the default size.
+  //
+  // Set to /netmask (e.g. `/14`) to have a range chosen with a specific
+  // netmask.
+  //
+  // Set to a
+  // [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing)
+  // notation (e.g. `10.96.0.0/14`) from the RFC-1918 private networks (e.g.
+  // `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) to pick a specific range
+  // to use.
+  string services_ipv4_cidr_block = 11;
+}
+
+// Configuration for the PodSecurityPolicy feature.
+message PodSecurityPolicyConfig {
+  // Enable the PodSecurityPolicy controller for this cluster. If enabled, pods
+  // must be valid under a PodSecurityPolicy to be created.
+  bool enabled = 1;
+}
+
+// A Google Container Engine cluster.
+message Cluster {
+  // The current status of the cluster.
+  enum Status {
+    // Not set.
+    STATUS_UNSPECIFIED = 0;
+
+    // The PROVISIONING state indicates the cluster is being created.
+    PROVISIONING = 1;
+
+    // The RUNNING state indicates the cluster has been created and is fully
+    // usable.
+    RUNNING = 2;
+
+    // The RECONCILING state indicates that some work is actively being done on
+    // the cluster, such as upgrading the master or node software. Details can
+    // be found in the `statusMessage` field.
+    RECONCILING = 3;
+
+    // The STOPPING state indicates the cluster is being deleted.
+    STOPPING = 4;
+
+    // The ERROR state indicates the cluster may be unusable. Details
+    // can be found in the `statusMessage` field.
+    ERROR = 5;
+  }
+
+  // The name of this cluster. The name must be unique within this project
+  // and zone, and can be up to 40 characters with the following restrictions:
+  //
+  // * Lowercase letters, numbers, and hyphens only.
+  // * Must start with a letter.
+  // * Must end with a number or a letter.
+  string name = 1;
+
+  // An optional description of this cluster.
+  string description = 2;
+
+  // The number of nodes to create in this cluster. You must ensure that your
+  // Compute Engine <a href="/compute/docs/resource-quotas">resource quota</a>
+  // is sufficient for this number of instances. You must also have available
+  // firewall and routes quota.
+  // For requests, this field should only be used in lieu of a
+  // "node_pool" object, since this configuration (along with the
+  // "node_config") will be used to create a "NodePool" object with an
+  // auto-generated name. Do not use this and a node_pool at the same time.
+  int32 initial_node_count = 3;
+
+  // Parameters used in creating the cluster's nodes.
+  // See `nodeConfig` for the description of its properties.
+  // For requests, this field should only be used in lieu of a
+  // "node_pool" object, since this configuration (along with the
+  // "initial_node_count") will be used to create a "NodePool" object with an
+  // auto-generated name. Do not use this and a node_pool at the same time.
+  // For responses, this field will be populated with the node configuration of
+  // the first node pool.
+  //
+  // If unspecified, the defaults are used.
+  NodeConfig node_config = 4;
+
+  // The authentication information for accessing the master endpoint.
+  MasterAuth master_auth = 5;
+
+  // The logging service the cluster should use to write logs.
+  // Currently available options:
+  //
+  // * `logging.googleapis.com` - the Google Cloud Logging service.
+  // * `none` - no logs will be exported from the cluster.
+  // * if left as an empty string,`logging.googleapis.com` will be used.
+  string logging_service = 6;
+
+  // The monitoring service the cluster should use to write metrics.
+  // Currently available options:
+  //
+  // * `monitoring.googleapis.com` - the Google Cloud Monitoring service.
+  // * `none` - no metrics will be exported from the cluster.
+  // * if left as an empty string, `monitoring.googleapis.com` will be used.
+  string monitoring_service = 7;
+
+  // The name of the Google Compute Engine
+  // [network](/compute/docs/networks-and-firewalls#networks) to which the
+  // cluster is connected. If left unspecified, the `default` network
+  // will be used.
+  string network = 8;
+
+  // The IP address range of the container pods in this cluster, in
+  // [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing)
+  // notation (e.g. `10.96.0.0/14`). Leave blank to have
+  // one automatically chosen or specify a `/14` block in `10.0.0.0/8`.
+  string cluster_ipv4_cidr = 9;
+
+  // Configurations for the various addons available to run in the cluster.
+  AddonsConfig addons_config = 10;
+
+  // The name of the Google Compute Engine
+  // [subnetwork](/compute/docs/subnetworks) to which the
+  // cluster is connected.
+  string subnetwork = 11;
+
+  // The node pools associated with this cluster.
+  // This field should not be set if "node_config" or "initial_node_count" are
+  // specified.
+  repeated NodePool node_pools = 12;
+
+  // The list of Google Compute Engine
+  // [locations](/compute/docs/zones#available) in which the cluster's nodes
+  // should be located.
+  repeated string locations = 13;
+
+  // Kubernetes alpha features are enabled on this cluster. This includes alpha
+  // API groups (e.g. v1alpha1) and features that may not be production ready in
+  // the kubernetes version of the master and nodes.
+  // The cluster has no SLA for uptime and master/node upgrades are disabled.
+  // Alpha enabled clusters are automatically deleted thirty days after
+  // creation.
+  bool enable_kubernetes_alpha = 14;
+
+  // Configuration options for the NetworkPolicy feature.
+  NetworkPolicy network_policy = 19;
+
+  // Configuration for cluster IP allocation.
+  IPAllocationPolicy ip_allocation_policy = 20;
+
+  // The configuration options for master authorized networks feature.
+  MasterAuthorizedNetworksConfig master_authorized_networks_config = 22;
+
+  // Configure the maintenance policy for this cluster.
+  MaintenancePolicy maintenance_policy = 23;
+
+  // Configuration for the PodSecurityPolicy feature.
+  PodSecurityPolicyConfig pod_security_policy_config = 25;
+
+  // [Output only] Server-defined URL for the resource.
+  string self_link = 100;
+
+  // [Output only] The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use location instead.
+  string zone = 101;
+
+  // [Output only] The IP address of this cluster's master endpoint.
+  // The endpoint can be accessed from the internet at
+  // `https://username:password@endpoint/`.
+  //
+  // See the `masterAuth` property of this resource for username and
+  // password information.
+  string endpoint = 102;
+
+  // The initial Kubernetes version for this cluster.  Valid versions are those
+  // found in validMasterVersions returned by getServerConfig.  The version can
+  // be upgraded over time; such upgrades are reflected in
+  // currentMasterVersion and currentNodeVersion.
+  string initial_cluster_version = 103;
+
+  // [Output only] The current software version of the master endpoint.
+  string current_master_version = 104;
+
+  // [Output only] The current version of the node software components.
+  // If they are currently at multiple versions because they're in the process
+  // of being upgraded, this reflects the minimum version of all nodes.
+  string current_node_version = 105;
+
+  // [Output only] The time the cluster was created, in
+  // [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format.
+  string create_time = 106;
+
+  // [Output only] The current status of this cluster.
+  Status status = 107;
+
+  // [Output only] Additional information about the current status of this
+  // cluster, if available.
+  string status_message = 108;
+
+  // [Output only] The size of the address space on each node for hosting
+  // containers. This is provisioned from within the `container_ipv4_cidr`
+  // range.
+  int32 node_ipv4_cidr_size = 109;
+
+  // [Output only] The IP address range of the Kubernetes services in
+  // this cluster, in
+  // [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing)
+  // notation (e.g. `1.2.3.4/29`). Service addresses are
+  // typically put in the last `/16` from the container CIDR.
+  string services_ipv4_cidr = 110;
+
+  // [Output only] The resource URLs of [instance
+  // groups](/compute/docs/instance-groups/) associated with this
+  // cluster.
+  repeated string instance_group_urls = 111;
+
+  // [Output only] The number of nodes currently in the cluster.
+  int32 current_node_count = 112;
+
+  // [Output only] The time the cluster will be automatically
+  // deleted in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format.
+  string expire_time = 113;
+
+  // [Output only] The name of the Google Compute Engine
+  // [zone](/compute/docs/regions-zones/regions-zones#available) or
+  // [region](/compute/docs/regions-zones/regions-zones#available) in which
+  // the cluster resides.
+  string location = 114;
+}
+
+// ClusterUpdate describes an update to the cluster. Exactly one update can
+// be applied to a cluster with each request, so at most one field can be
+// provided.
+message ClusterUpdate {
+  // The Kubernetes version to change the nodes to (typically an
+  // upgrade). Use `-` to upgrade to the latest version supported by
+  // the server.
+  string desired_node_version = 4;
+
+  // The monitoring service the cluster should use to write metrics.
+  // Currently available options:
+  //
+  // * "monitoring.googleapis.com" - the Google Cloud Monitoring service
+  // * "none" - no metrics will be exported from the cluster
+  string desired_monitoring_service = 5;
+
+  // Configurations for the various addons available to run in the cluster.
+  AddonsConfig desired_addons_config = 6;
+
+  // The node pool to be upgraded. This field is mandatory if
+  // "desired_node_version", "desired_image_family" or
+  // "desired_node_pool_autoscaling" is specified and there is more than one
+  // node pool on the cluster.
+  string desired_node_pool_id = 7;
+
+  // The desired image type for the node pool.
+  // NOTE: Set the "desired_node_pool" field as well.
+  string desired_image_type = 8;
+
+  // Autoscaler configuration for the node pool specified in
+  // desired_node_pool_id. If there is only one pool in the
+  // cluster and desired_node_pool_id is not provided then
+  // the change applies to that single node pool.
+  NodePoolAutoscaling desired_node_pool_autoscaling = 9;
+
+  // The desired list of Google Compute Engine
+  // [locations](/compute/docs/zones#available) in which the cluster's nodes
+  // should be located. Changing the locations a cluster is in will result
+  // in nodes being either created or removed from the cluster, depending on
+  // whether locations are being added or removed.
+  //
+  // This list must always include the cluster's primary zone.
+  repeated string desired_locations = 10;
+
+  // The desired configuration options for master authorized networks feature.
+  MasterAuthorizedNetworksConfig desired_master_authorized_networks_config = 12;
+
+  // The desired configuration options for the PodSecurityPolicy feature.
+  PodSecurityPolicyConfig desired_pod_security_policy_config = 14;
+
+  // The Kubernetes version to change the master to. The only valid value is the
+  // latest supported version. Use "-" to have the server automatically select
+  // the latest version.
+  string desired_master_version = 100;
+}
+
+// This operation resource represents operations that may have happened or are
+// happening on the cluster. All fields are output only.
+message Operation {
+  // Current status of the operation.
+  enum Status {
+    // Not set.
+    STATUS_UNSPECIFIED = 0;
+
+    // The operation has been created.
+    PENDING = 1;
+
+    // The operation is currently running.
+    RUNNING = 2;
+
+    // The operation is done, either cancelled or completed.
+    DONE = 3;
+
+    // The operation is aborting.
+    ABORTING = 4;
+  }
+
+  // Operation type.
+  enum Type {
+    // Not set.
+    TYPE_UNSPECIFIED = 0;
+
+    // Cluster create.
+    CREATE_CLUSTER = 1;
+
+    // Cluster delete.
+    DELETE_CLUSTER = 2;
+
+    // A master upgrade.
+    UPGRADE_MASTER = 3;
+
+    // A node upgrade.
+    UPGRADE_NODES = 4;
+
+    // Cluster repair.
+    REPAIR_CLUSTER = 5;
+
+    // Cluster update.
+    UPDATE_CLUSTER = 6;
+
+    // Node pool create.
+    CREATE_NODE_POOL = 7;
+
+    // Node pool delete.
+    DELETE_NODE_POOL = 8;
+
+    // Set node pool management.
+    SET_NODE_POOL_MANAGEMENT = 9;
+
+    // Automatic node pool repair.
+    AUTO_REPAIR_NODES = 10;
+
+    // Automatic node upgrade.
+    AUTO_UPGRADE_NODES = 11;
+
+    // Set labels.
+    SET_LABELS = 12;
+
+    // Set/generate master auth materials
+    SET_MASTER_AUTH = 13;
+
+    // Set node pool size.
+    SET_NODE_POOL_SIZE = 14;
+
+    // Updates network policy for a cluster.
+    SET_NETWORK_POLICY = 15;
+
+    // Set the maintenance policy.
+    SET_MAINTENANCE_POLICY = 16;
+  }
+
+  // The server-assigned ID for the operation.
+  string name = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the operation
+  // is taking place.
+  // This field is deprecated, use location instead.
+  string zone = 2;
+
+  // The operation type.
+  Type operation_type = 3;
+
+  // The current status of the operation.
+  Status status = 4;
+
+  // Detailed operation progress, if available.
+  string detail = 8;
+
+  // If an error has occurred, a textual description of the error.
+  string status_message = 5;
+
+  // Server-defined URL for the resource.
+  string self_link = 6;
+
+  // Server-defined URL for the target of the operation.
+  string target_link = 7;
+
+  // [Output only] The name of the Google Compute Engine
+  // [zone](/compute/docs/regions-zones/regions-zones#available) or
+  // [region](/compute/docs/regions-zones/regions-zones#available) in which
+  // the cluster resides.
+  string location = 9;
+
+  // [Output only] The time the operation started, in
+  // [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format.
+  string start_time = 10;
+
+  // [Output only] The time the operation completed, in
+  // [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format.
+  string end_time = 11;
+}
+
+// CreateClusterRequest creates a cluster.
+message CreateClusterRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use parent instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use parent instead.
+  string zone = 2;
+
+  // A [cluster
+  // resource](/container-engine/reference/rest/v1alpha1/projects.zones.clusters)
+  Cluster cluster = 3;
+
+  // The parent (project and location) where the cluster will be created.
+  // Specified in the format 'projects/*/locations/*'.
+  string parent = 5;
+}
+
+// GetClusterRequest gets the settings of a cluster.
+message GetClusterRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to retrieve.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name (project, location, cluster) of the cluster to retrieve.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 5;
+}
+
+// UpdateClusterRequest updates the settings of a cluster.
+message UpdateClusterRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to upgrade.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // A description of the update.
+  ClusterUpdate update = 4;
+
+  // The name (project, location, cluster) of the cluster to update.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 5;
+}
+
+// SetNodePoolVersionRequest updates the version of a node pool.
+message UpdateNodePoolRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to upgrade.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name of the node pool to upgrade.
+  // This field is deprecated, use name instead.
+  string node_pool_id = 4;
+
+  // The Kubernetes version to change the nodes to (typically an
+  // upgrade). Use `-` to upgrade to the latest version supported by
+  // the server.
+  string node_version = 5;
+
+  // The desired image type for the node pool.
+  string image_type = 6;
+
+  // The name (project, location, cluster, node pool) of the node pool to update.
+  // Specified in the format 'projects/*/locations/*/clusters/*/nodePools/*'.
+  string name = 8;
+}
+
+// SetNodePoolAutoscalingRequest sets the autoscaler settings of a node pool.
+message SetNodePoolAutoscalingRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to upgrade.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name of the node pool to upgrade.
+  // This field is deprecated, use name instead.
+  string node_pool_id = 4;
+
+  // Autoscaling configuration for the node pool.
+  NodePoolAutoscaling autoscaling = 5;
+
+  // The name (project, location, cluster, node pool) of the node pool to set
+  // autoscaler settings. Specified in the format
+  // 'projects/*/locations/*/clusters/*/nodePools/*'.
+  string name = 6;
+}
+
+// SetLoggingServiceRequest sets the logging service of a cluster.
+message SetLoggingServiceRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  string zone = 2;
+
+  // The name of the cluster to upgrade.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The logging service the cluster should use to write metrics.
+  // Currently available options:
+  //
+  // * "logging.googleapis.com" - the Google Cloud Logging service
+  // * "none" - no metrics will be exported from the cluster
+  string logging_service = 4;
+
+  // The name (project, location, cluster) of the cluster to set logging.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 5;
+}
+
+// SetMonitoringServiceRequest sets the monitoring service of a cluster.
+message SetMonitoringServiceRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to upgrade.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The monitoring service the cluster should use to write metrics.
+  // Currently available options:
+  //
+  // * "monitoring.googleapis.com" - the Google Cloud Monitoring service
+  // * "none" - no metrics will be exported from the cluster
+  string monitoring_service = 4;
+
+  // The name (project, location, cluster) of the cluster to set monitoring.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 6;
+}
+
+// SetAddonsRequest sets the addons associated with the cluster.
+message SetAddonsConfigRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to upgrade.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The desired configurations for the various addons available to run in the
+  // cluster.
+  AddonsConfig addons_config = 4;
+
+  // The name (project, location, cluster) of the cluster to set addons.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 6;
+}
+
+// SetLocationsRequest sets the locations of the cluster.
+message SetLocationsRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to upgrade.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The desired list of Google Compute Engine
+  // [locations](/compute/docs/zones#available) in which the cluster's nodes
+  // should be located. Changing the locations a cluster is in will result
+  // in nodes being either created or removed from the cluster, depending on
+  // whether locations are being added or removed.
+  //
+  // This list must always include the cluster's primary zone.
+  repeated string locations = 4;
+
+  // The name (project, location, cluster) of the cluster to set locations.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 6;
+}
+
+// UpdateMasterRequest updates the master of the cluster.
+message UpdateMasterRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to upgrade.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The Kubernetes version to change the master to. The only valid value is the
+  // latest supported version. Use "-" to have the server automatically select
+  // the latest version.
+  string master_version = 4;
+
+  // The name (project, location, cluster) of the cluster to update.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 7;
+}
+
+// SetMasterAuthRequest updates the admin password of a cluster.
+message SetMasterAuthRequest {
+  // Operation type: what type update to perform.
+  enum Action {
+    // Operation is unknown and will error out.
+    UNKNOWN = 0;
+
+    // Set the password to a user generated value.
+    SET_PASSWORD = 1;
+
+    // Generate a new password and set it to that.
+    GENERATE_PASSWORD = 2;
+
+    // Set the username.  If an empty username is provided, basic authentication
+    // is disabled for the cluster.  If a non-empty username is provided, basic
+    // authentication is enabled, with either a provided password or a generated
+    // one.
+    SET_USERNAME = 3;
+  }
+
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to upgrade.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The exact form of action to be taken on the master auth.
+  Action action = 4;
+
+  // A description of the update.
+  MasterAuth update = 5;
+
+  // The name (project, location, cluster) of the cluster to set auth.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 7;
+}
+
+// DeleteClusterRequest deletes a cluster.
+message DeleteClusterRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to delete.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name (project, location, cluster) of the cluster to delete.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 4;
+}
+
+// ListClustersRequest lists clusters.
+message ListClustersRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use parent instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides, or "-" for all zones.
+  // This field is deprecated, use parent instead.
+  string zone = 2;
+
+  // The parent (project and location) where the clusters will be listed.
+  // Specified in the format 'projects/*/locations/*'.
+  // Location "-" matches all zones and all regions.
+  string parent = 4;
+}
+
+// ListClustersResponse is the result of ListClustersRequest.
+message ListClustersResponse {
+  // A list of clusters in the project in the specified zone, or
+  // across all ones.
+  repeated Cluster clusters = 1;
+
+  // If any zones are listed here, the list of clusters returned
+  // may be missing those zones.
+  repeated string missing_zones = 2;
+}
+
+// GetOperationRequest gets a single operation.
+message GetOperationRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The server-assigned `name` of the operation.
+  // This field is deprecated, use name instead.
+  string operation_id = 3;
+
+  // The name (project, location, operation id) of the operation to get.
+  // Specified in the format 'projects/*/locations/*/operations/*'.
+  string name = 5;
+}
+
+// ListOperationsRequest lists operations.
+message ListOperationsRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use parent instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine [zone](/compute/docs/zones#available)
+  // to return operations for, or `-` for all zones.
+  // This field is deprecated, use parent instead.
+  string zone = 2;
+
+  // The parent (project and location) where the operations will be listed.
+  // Specified in the format 'projects/*/locations/*'.
+  // Location "-" matches all zones and all regions.
+  string parent = 4;
+}
+
+// CancelOperationRequest cancels a single operation.
+message CancelOperationRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the operation resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The server-assigned `name` of the operation.
+  // This field is deprecated, use name instead.
+  string operation_id = 3;
+
+  // The name (project, location, operation id) of the operation to cancel.
+  // Specified in the format 'projects/*/locations/*/operations/*'.
+  string name = 4;
+}
+
+// ListOperationsResponse is the result of ListOperationsRequest.
+message ListOperationsResponse {
+  // A list of operations in the project in the specified zone.
+  repeated Operation operations = 1;
+
+  // If any zones are listed here, the list of operations returned
+  // may be missing the operations from those zones.
+  repeated string missing_zones = 2;
+}
+
+// Gets the current Container Engine service configuration.
+message GetServerConfigRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine [zone](/compute/docs/zones#available)
+  // to return operations for.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name (project and location) of the server config to get
+  // Specified in the format 'projects/*/locations/*'.
+  string name = 4;
+}
+
+// Container Engine service configuration.
+message ServerConfig {
+  // Version of Kubernetes the service deploys by default.
+  string default_cluster_version = 1;
+
+  // List of valid node upgrade target versions.
+  repeated string valid_node_versions = 3;
+
+  // Default image type.
+  string default_image_type = 4;
+
+  // List of valid image types.
+  repeated string valid_image_types = 5;
+
+  // List of valid master versions.
+  repeated string valid_master_versions = 6;
+}
+
+// CreateNodePoolRequest creates a node pool for a cluster.
+message CreateNodePoolRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://developers.google.com/console/help/new/#projectnumber).
+  // This field is deprecated, use parent instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use parent instead.
+  string zone = 2;
+
+  // The name of the cluster.
+  // This field is deprecated, use parent instead.
+  string cluster_id = 3;
+
+  // The node pool to create.
+  NodePool node_pool = 4;
+
+  // The parent (project, location, cluster id) where the node pool will be created.
+  // Specified in the format 'projects/*/locations/*/clusters/*/nodePools/*'.
+  string parent = 6;
+}
+
+// DeleteNodePoolRequest deletes a node pool for a cluster.
+message DeleteNodePoolRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://developers.google.com/console/help/new/#projectnumber).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name of the node pool to delete.
+  // This field is deprecated, use name instead.
+  string node_pool_id = 4;
+
+  // The name (project, location, cluster, node pool id) of the node pool to delete.
+  // Specified in the format 'projects/*/locations/*/clusters/*/nodePools/*'.
+  string name = 6;
+}
+
+// ListNodePoolsRequest lists the node pool(s) for a cluster.
+message ListNodePoolsRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://developers.google.com/console/help/new/#projectnumber).
+  // This field is deprecated, use parent instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use parent instead.
+  string zone = 2;
+
+  // The name of the cluster.
+  // This field is deprecated, use parent instead.
+  string cluster_id = 3;
+
+  // The parent (project, location, cluster id) where the node pools will be listed.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string parent = 5;
+}
+
+// GetNodePoolRequest retrieves a node pool for a cluster.
+message GetNodePoolRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://developers.google.com/console/help/new/#projectnumber).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name of the node pool.
+  // This field is deprecated, use name instead.
+  string node_pool_id = 4;
+
+  // The name (project, location, cluster, node pool id) of the node pool to get.
+  // Specified in the format 'projects/*/locations/*/clusters/*/nodePools/*'.
+  string name = 6;
+}
+
+// NodePool contains the name and configuration for a cluster's node pool.
+// Node pools are a set of nodes (i.e. VM's), with a common configuration and
+// specification, under the control of the cluster master. They may have a set
+// of Kubernetes labels applied to them, which may be used to reference them
+// during pod scheduling. They may also be resized up or down, to accommodate
+// the workload.
+message NodePool {
+  // The current status of the node pool instance.
+  enum Status {
+    // Not set.
+    STATUS_UNSPECIFIED = 0;
+
+    // The PROVISIONING state indicates the node pool is being created.
+    PROVISIONING = 1;
+
+    // The RUNNING state indicates the node pool has been created
+    // and is fully usable.
+    RUNNING = 2;
+
+    // The RUNNING_WITH_ERROR state indicates the node pool has been created
+    // and is partially usable. Some error state has occurred and some
+    // functionality may be impaired. Customer may need to reissue a request
+    // or trigger a new update.
+    RUNNING_WITH_ERROR = 3;
+
+    // The RECONCILING state indicates that some work is actively being done on
+    // the node pool, such as upgrading node software. Details can
+    // be found in the `statusMessage` field.
+    RECONCILING = 4;
+
+    // The STOPPING state indicates the node pool is being deleted.
+    STOPPING = 5;
+
+    // The ERROR state indicates the node pool may be unusable. Details
+    // can be found in the `statusMessage` field.
+    ERROR = 6;
+  }
+
+  // The name of the node pool.
+  string name = 1;
+
+  // The node configuration of the pool.
+  NodeConfig config = 2;
+
+  // The initial node count for the pool. You must ensure that your
+  // Compute Engine <a href="/compute/docs/resource-quotas">resource quota</a>
+  // is sufficient for this number of instances. You must also have available
+  // firewall and routes quota.
+  int32 initial_node_count = 3;
+
+  // Autoscaler configuration for this NodePool. Autoscaler is enabled
+  // only if a valid configuration is present.
+  NodePoolAutoscaling autoscaling = 4;
+
+  // NodeManagement configuration for this NodePool.
+  NodeManagement management = 5;
+
+  // [Output only] Server-defined URL for the resource.
+  string self_link = 100;
+
+  // [Output only] The version of the Kubernetes of this node.
+  string version = 101;
+
+  // [Output only] The resource URLs of [instance
+  // groups](/compute/docs/instance-groups/) associated with this
+  // node pool.
+  repeated string instance_group_urls = 102;
+
+  // [Output only] The status of the nodes in this pool instance.
+  Status status = 103;
+
+  // [Output only] Additional information about the current status of this
+  // node pool instance, if available.
+  string status_message = 104;
+}
+
+// NodeManagement defines the set of node management services turned on for the
+// node pool.
+message NodeManagement {
+  // Whether the nodes will be automatically upgraded.
+  bool auto_upgrade = 1;
+
+  // Whether the nodes will be automatically repaired.
+  bool auto_repair = 2;
+
+  // Specifies the Auto Upgrade knobs for the node pool.
+  AutoUpgradeOptions upgrade_options = 10;
+}
+
+// AutoUpgradeOptions defines the set of options for the user to control how
+// the Auto Upgrades will proceed.
+message AutoUpgradeOptions {
+  // [Output only] This field is set when upgrades are about to commence
+  // with the approximate start time for the upgrades, in
+  // [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format.
+  string auto_upgrade_start_time = 1;
+
+  // [Output only] This field is set when upgrades are about to commence
+  // with the description of the upgrade.
+  string description = 2;
+}
+
+// MaintenancePolicy defines the maintenance policy to be used for the cluster.
+message MaintenancePolicy {
+  // Specifies the maintenance window in which maintenance may be performed.
+  MaintenanceWindow window = 1;
+}
+
+// MaintenanceWindow defines the maintenance window to be used for the cluster.
+message MaintenanceWindow {
+  // Unimplemented, reserved for future use.
+  // HourlyMaintenanceWindow hourly_maintenance_window = 1;
+  oneof policy {
+    // DailyMaintenanceWindow specifies a daily maintenance operation window.
+    DailyMaintenanceWindow daily_maintenance_window = 2;
+  }
+}
+
+// Time window specified for daily maintenance operations.
+message DailyMaintenanceWindow {
+  // Time within the maintenance window to start the maintenance operations.
+  // It must be in format "HH:MM”, where HH : [00-23] and MM : [00-59] GMT.
+  string start_time = 2;
+
+  // [Output only] Duration of the time window, automatically chosen to be
+  // smallest possible in the given scenario.
+  string duration = 3;
+}
+
+// SetNodePoolManagementRequest sets the node management properties of a node
+// pool.
+message SetNodePoolManagementRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to update.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name of the node pool to update.
+  // This field is deprecated, use name instead.
+  string node_pool_id = 4;
+
+  // NodeManagement configuration for the node pool.
+  NodeManagement management = 5;
+
+  // The name (project, location, cluster, node pool id) of the node pool to set
+  // management properties. Specified in the format
+  // 'projects/*/locations/*/clusters/*/nodePools/*'.
+  string name = 7;
+}
+
+// SetNodePoolSizeRequest sets the size a node
+// pool.
+message SetNodePoolSizeRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to update.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name of the node pool to update.
+  // This field is deprecated, use name instead.
+  string node_pool_id = 4;
+
+  // The desired node count for the pool.
+  int32 node_count = 5;
+
+  // The name (project, location, cluster, node pool id) of the node pool to set
+  // size.
+  // Specified in the format 'projects/*/locations/*/clusters/*/nodePools/*'.
+  string name = 7;
+}
+
+// RollbackNodePoolUpgradeRequest rollbacks the previously Aborted or Failed
+// NodePool upgrade. This will be an no-op if the last upgrade successfully
+// completed.
+message RollbackNodePoolUpgradeRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to rollback.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name of the node pool to rollback.
+  // This field is deprecated, use name instead.
+  string node_pool_id = 4;
+
+  // The name (project, location, cluster, node pool id) of the node poll to
+  // rollback upgrade.
+  // Specified in the format 'projects/*/locations/*/clusters/*/nodePools/*'.
+  string name = 6;
+}
+
+// ListNodePoolsResponse is the result of ListNodePoolsRequest.
+message ListNodePoolsResponse {
+  // A list of node pools for a cluster.
+  repeated NodePool node_pools = 1;
+}
+
+// NodePoolAutoscaling contains information required by cluster autoscaler to
+// adjust the size of the node pool to the current cluster usage.
+message NodePoolAutoscaling {
+  // Is autoscaling enabled for this node pool.
+  bool enabled = 1;
+
+  // Minimum number of nodes in the NodePool. Must be >= 1 and <=
+  // max_node_count.
+  int32 min_node_count = 2;
+
+  // Maximum number of nodes in the NodePool. Must be >= min_node_count. There
+  // has to enough quota to scale up the cluster.
+  int32 max_node_count = 3;
+}
+
+// SetLabelsRequest sets the Google Cloud Platform labels on a Google Container
+// Engine cluster, which will in turn set them for Google Compute Engine
+// resources used by that cluster
+message SetLabelsRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://developers.google.com/console/help/new/#projectnumber).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The labels to set for that cluster.
+  map<string, string> resource_labels = 4;
+
+  // The fingerprint of the previous set of labels for this resource,
+  // used to detect conflicts. The fingerprint is initially generated by
+  // Container Engine and changes after every request to modify or update
+  // labels. You must always provide an up-to-date fingerprint hash when
+  // updating or changing labels. Make a <code>get()</code> request to the
+  // resource to get the latest fingerprint.
+  string label_fingerprint = 5;
+
+  // The name (project, location, cluster id) of the cluster to set labels.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 7;
+}
+
+// SetLegacyAbacRequest enables or disables the ABAC authorization mechanism for
+// a cluster.
+message SetLegacyAbacRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster to update.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // Whether ABAC authorization will be enabled in the cluster.
+  bool enabled = 4;
+
+  // The name (project, location, cluster id) of the cluster to set legacy abac.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 6;
+}
+
+// StartIPRotationRequest creates a new IP for the cluster and then performs
+// a node upgrade on each node pool to point to the new IP.
+message StartIPRotationRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://developers.google.com/console/help/new/#projectnumber).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name (project, location, cluster id) of the cluster to start IP rotation.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 6;
+}
+
+// CompleteIPRotationRequest moves the cluster master back into single-IP mode.
+message CompleteIPRotationRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://developers.google.com/console/help/new/#projectnumber).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // The name (project, location, cluster id) of the cluster to complete IP rotation.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 7;
+}
+
+// AcceleratorConfig represents a Hardware Accelerator request.
+message AcceleratorConfig {
+  // The number of the accelerator cards exposed to an instance.
+  int64 accelerator_count = 1;
+
+  // The accelerator type resource name. List of supported accelerators
+  // [here](/compute/docs/gpus/#Introduction)
+  string accelerator_type = 2;
+}
+
+// SetNetworkPolicyRequest enables/disables network policy for a cluster.
+message SetNetworkPolicyRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://developers.google.com/console/help/new/#projectnumber).
+  // This field is deprecated, use name instead.
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  // This field is deprecated, use name instead.
+  string zone = 2;
+
+  // The name of the cluster.
+  // This field is deprecated, use name instead.
+  string cluster_id = 3;
+
+  // Configuration options for the NetworkPolicy feature.
+  NetworkPolicy network_policy = 4;
+
+  // The name (project, location, cluster id) of the cluster to set networking
+  // policy.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 6;
+}
+
+// SetMaintenancePolicyRequest sets the maintenance policy for a cluster.
+message SetMaintenancePolicyRequest {
+  // The Google Developers Console [project ID or project
+  // number](https://support.google.com/cloud/answer/6158840).
+  string project_id = 1;
+
+  // The name of the Google Compute Engine
+  // [zone](/compute/docs/zones#available) in which the cluster
+  // resides.
+  string zone = 2;
+
+  // The name of the cluster to update.
+  string cluster_id = 3;
+
+  // The maintenance policy to be set for the cluster. An empty field
+  // clears the existing maintenance policy.
+  MaintenancePolicy maintenance_policy = 4;
+
+  // The name (project, location, cluster id) of the cluster to set maintenance
+  // policy.
+  // Specified in the format 'projects/*/locations/*/clusters/*'.
+  string name = 5;
+}
diff --git a/container/google/cloud/container_v1/proto/cluster_service_pb2.py b/container/google/cloud/container_v1/proto/cluster_service_pb2.py
index 65d0e214d534..ae792c31deab 100644
--- a/container/google/cloud/container_v1/proto/cluster_service_pb2.py
+++ b/container/google/cloud/container_v1/proto/cluster_service_pb2.py
@@ -9841,3 +9841,4 @@
 DESCRIPTOR.services_by_name["ClusterManager"] = _CLUSTERMANAGER
 
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/container/synth.metadata b/container/synth.metadata
index 804e84fe1133..06bbbde3d2fe 100644
--- a/container/synth.metadata
+++ b/container/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:14:49.534930Z",
+  "updateTime": "2019-01-23T22:47:01.249327Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/container/synth.py b/container/synth.py
index 93df9ecc8adf..d54a56a44d15 100644
--- a/container/synth.py
+++ b/container/synth.py
@@ -27,6 +27,7 @@
     "v1",
     config_path="/google/container/artman_container_v1.yaml",
     artman_output_name="container-v1",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/container_v1")
diff --git a/dataproc/google/cloud/dataproc_v1/proto/clusters.proto b/dataproc/google/cloud/dataproc_v1/proto/clusters.proto
new file mode 100644
index 000000000000..fd3c86a0ffb8
--- /dev/null
+++ b/dataproc/google/cloud/dataproc_v1/proto/clusters.proto
@@ -0,0 +1,731 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.dataproc.v1beta2;
+
+import "google/api/annotations.proto";
+import "google/cloud/dataproc/v1beta2/shared.proto";
+import "google/cloud/dataproc/v1beta2/operations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2;dataproc";
+option java_multiple_files = true;
+option java_outer_classname = "ClustersProto";
+option java_package = "com.google.cloud.dataproc.v1beta2";
+
+
+// The ClusterControllerService provides methods to manage clusters
+// of Compute Engine instances.
+service ClusterController {
+  // Creates a cluster in a project.
+  rpc CreateCluster(CreateClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta2/projects/{project_id}/regions/{region}/clusters"
+      body: "cluster"
+    };
+  }
+
+  // Updates a cluster in a project.
+  rpc UpdateCluster(UpdateClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v1beta2/projects/{project_id}/regions/{region}/clusters/{cluster_name}"
+      body: "cluster"
+    };
+  }
+
+  // Deletes a cluster in a project.
+  rpc DeleteCluster(DeleteClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      delete: "/v1beta2/projects/{project_id}/regions/{region}/clusters/{cluster_name}"
+    };
+  }
+
+  // Gets the resource representation for a cluster in a project.
+  rpc GetCluster(GetClusterRequest) returns (Cluster) {
+    option (google.api.http) = {
+      get: "/v1beta2/projects/{project_id}/regions/{region}/clusters/{cluster_name}"
+    };
+  }
+
+  // Lists all regions/{region}/clusters in a project.
+  rpc ListClusters(ListClustersRequest) returns (ListClustersResponse) {
+    option (google.api.http) = {
+      get: "/v1beta2/projects/{project_id}/regions/{region}/clusters"
+    };
+  }
+
+  // Gets cluster diagnostic information.
+  // After the operation completes, the Operation.response field
+  // contains `DiagnoseClusterOutputLocation`.
+  rpc DiagnoseCluster(DiagnoseClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta2/projects/{project_id}/regions/{region}/clusters/{cluster_name}:diagnose"
+      body: "*"
+    };
+  }
+}
+
+// Describes the identifying information, config, and status of
+// a cluster of Compute Engine instances.
+message Cluster {
+  // Required. The Google Cloud Platform project ID that the cluster belongs to.
+  string project_id = 1;
+
+  // Required. The cluster name. Cluster names within a project must be
+  // unique. Names of deleted clusters can be reused.
+  string cluster_name = 2;
+
+  // Required. The cluster config. Note that Cloud Dataproc may set
+  // default values, and values may change when clusters are updated.
+  ClusterConfig config = 3;
+
+  // Optional. The labels to associate with this cluster.
+  // Label **keys** must contain 1 to 63 characters, and must conform to
+  // [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  // Label **values** may be empty, but, if present, must contain 1 to 63
+  // characters, and must conform to [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  // No more than 32 labels can be associated with a cluster.
+  map<string, string> labels = 8;
+
+  // Output only. Cluster status.
+  ClusterStatus status = 4;
+
+  // Output only. The previous cluster status.
+  repeated ClusterStatus status_history = 7;
+
+  // Output only. A cluster UUID (Unique Universal Identifier). Cloud Dataproc
+  // generates this value when it creates the cluster.
+  string cluster_uuid = 6;
+
+  // Output only. Contains cluster daemon metrics such as HDFS and YARN stats.
+  //
+  // **Beta Feature**: This report is available for testing purposes only. It may
+  // be changed before final release.
+  ClusterMetrics metrics = 9;
+}
+
+// The cluster config.
+message ClusterConfig {
+  // Optional. A Cloud Storage staging bucket used for sharing generated
+  // SSH keys and config. If you do not specify a staging bucket, Cloud
+  // Dataproc will determine an appropriate Cloud Storage location (US,
+  // ASIA, or EU) for your cluster's staging bucket according to the Google
+  // Compute Engine zone where your cluster is deployed, and then it will create
+  // and manage this project-level, per-location bucket for you.
+  string config_bucket = 1;
+
+  // Required. The shared Compute Engine config settings for
+  // all instances in a cluster.
+  GceClusterConfig gce_cluster_config = 8;
+
+  // Optional. The Compute Engine config settings for
+  // the master instance in a cluster.
+  InstanceGroupConfig master_config = 9;
+
+  // Optional. The Compute Engine config settings for
+  // worker instances in a cluster.
+  InstanceGroupConfig worker_config = 10;
+
+  // Optional. The Compute Engine config settings for
+  // additional worker instances in a cluster.
+  InstanceGroupConfig secondary_worker_config = 12;
+
+  // Optional. The config settings for software inside the cluster.
+  SoftwareConfig software_config = 13;
+
+  // Optional. The config setting for auto delete cluster schedule.
+  LifecycleConfig lifecycle_config = 14;
+
+  // Optional. Commands to execute on each node after config is
+  // completed. By default, executables are run on master and all worker nodes.
+  // You can test a node's <code>role</code> metadata to run an executable on
+  // a master or worker node, as shown below using `curl` (you can also use `wget`):
+  //
+  //     ROLE=$(curl -H Metadata-Flavor:Google http://metadata/computeMetadata/v1beta2/instance/attributes/dataproc-role)
+  //     if [[ "${ROLE}" == 'Master' ]]; then
+  //       ... master specific actions ...
+  //     else
+  //       ... worker specific actions ...
+  //     fi
+  repeated NodeInitializationAction initialization_actions = 11;
+
+  // Optional. Encryption settings for the cluster.
+  EncryptionConfig encryption_config = 15;
+}
+
+// Encryption settings for the cluster.
+message EncryptionConfig {
+  // Optional. The Cloud KMS key name to use for PD disk encryption for all
+  // instances in the cluster.
+  string gce_pd_kms_key_name = 1;
+}
+
+// Common config settings for resources of Compute Engine cluster
+// instances, applicable to all instances in the cluster.
+message GceClusterConfig {
+  // Optional. The zone where the Compute Engine cluster will be located.
+  // On a create request, it is required in the "global" region. If omitted
+  // in a non-global Cloud Dataproc region, the service will pick a zone in the
+  // corresponding Compute Engine region. On a get request, zone will always be
+  // present.
+  //
+  // A full URL, partial URI, or short name are valid. Examples:
+  //
+  // * `https://www.googleapis.com/compute/v1/projects/[project_id]/zones/[zone]`
+  // * `projects/[project_id]/zones/[zone]`
+  // * `us-central1-f`
+  string zone_uri = 1;
+
+  // Optional. The Compute Engine network to be used for machine
+  // communications. Cannot be specified with subnetwork_uri. If neither
+  // `network_uri` nor `subnetwork_uri` is specified, the "default" network of
+  // the project is used, if it exists. Cannot be a "Custom Subnet Network" (see
+  // [Using Subnetworks](/compute/docs/subnetworks) for more information).
+  //
+  // A full URL, partial URI, or short name are valid. Examples:
+  //
+  // * `https://www.googleapis.com/compute/v1/projects/[project_id]/regions/global/default`
+  // * `projects/[project_id]/regions/global/default`
+  // * `default`
+  string network_uri = 2;
+
+  // Optional. The Compute Engine subnetwork to be used for machine
+  // communications. Cannot be specified with network_uri.
+  //
+  // A full URL, partial URI, or short name are valid. Examples:
+  //
+  // * `https://www.googleapis.com/compute/v1/projects/[project_id]/regions/us-east1/sub0`
+  // * `projects/[project_id]/regions/us-east1/sub0`
+  // * `sub0`
+  string subnetwork_uri = 6;
+
+  // Optional. If true, all instances in the cluster will only have internal IP
+  // addresses. By default, clusters are not restricted to internal IP addresses,
+  // and will have ephemeral external IP addresses assigned to each instance.
+  // This `internal_ip_only` restriction can only be enabled for subnetwork
+  // enabled networks, and all off-cluster dependencies must be configured to be
+  // accessible without external IP addresses.
+  bool internal_ip_only = 7;
+
+  // Optional. The service account of the instances. Defaults to the default
+  // Compute Engine service account. Custom service accounts need
+  // permissions equivalent to the following IAM roles:
+  //
+  // * roles/logging.logWriter
+  // * roles/storage.objectAdmin
+  //
+  // (see https://cloud.google.com/compute/docs/access/service-accounts#custom_service_accounts
+  // for more information).
+  // Example: `[account_id]@[project_id].iam.gserviceaccount.com`
+  string service_account = 8;
+
+  // Optional. The URIs of service account scopes to be included in
+  // Compute Engine instances. The following base set of scopes is always
+  // included:
+  //
+  // * https://www.googleapis.com/auth/cloud.useraccounts.readonly
+  // * https://www.googleapis.com/auth/devstorage.read_write
+  // * https://www.googleapis.com/auth/logging.write
+  //
+  // If no scopes are specified, the following defaults are also provided:
+  //
+  // * https://www.googleapis.com/auth/bigquery
+  // * https://www.googleapis.com/auth/bigtable.admin.table
+  // * https://www.googleapis.com/auth/bigtable.data
+  // * https://www.googleapis.com/auth/devstorage.full_control
+  repeated string service_account_scopes = 3;
+
+  // The Compute Engine tags to add to all instances (see
+  // [Tagging instances](/compute/docs/label-or-tag-resources#tags)).
+  repeated string tags = 4;
+
+  // The Compute Engine metadata entries to add to all instances (see
+  // [Project and instance metadata](https://cloud.google.com/compute/docs/storing-retrieving-metadata#project_and_instance_metadata)).
+  map<string, string> metadata = 5;
+}
+
+// Optional. The config settings for Compute Engine resources in
+// an instance group, such as a master or worker group.
+message InstanceGroupConfig {
+  // Optional. The number of VM instances in the instance group.
+  // For master instance groups, must be set to 1.
+  int32 num_instances = 1;
+
+  // Output only. The list of instance names. Cloud Dataproc derives the names
+  // from `cluster_name`, `num_instances`, and the instance group.
+  repeated string instance_names = 2;
+
+  // Optional. The Compute Engine image resource used for cluster
+  // instances. It can be specified or may be inferred from
+  // `SoftwareConfig.image_version`.
+  string image_uri = 3;
+
+  // Optional. The Compute Engine machine type used for cluster instances.
+  //
+  // A full URL, partial URI, or short name are valid. Examples:
+  //
+  // * `https://www.googleapis.com/compute/v1/projects/[project_id]/zones/us-east1-a/machineTypes/n1-standard-2`
+  // * `projects/[project_id]/zones/us-east1-a/machineTypes/n1-standard-2`
+  // * `n1-standard-2`
+  //
+  // **Auto Zone Exception**: If you are using the Cloud Dataproc
+  // [Auto Zone Placement](/dataproc/docs/concepts/configuring-clusters/auto-zone#using_auto_zone_placement)
+  // feature, you must use the short name of the machine type
+  // resource, for example, `n1-standard-2`.
+  string machine_type_uri = 4;
+
+  // Optional. Disk option config settings.
+  DiskConfig disk_config = 5;
+
+  // Optional. Specifies that this instance group contains preemptible instances.
+  bool is_preemptible = 6;
+
+  // Output only. The config for Compute Engine Instance Group
+  // Manager that manages this group.
+  // This is only used for preemptible instance groups.
+  ManagedGroupConfig managed_group_config = 7;
+
+  // Optional. The Compute Engine accelerator configuration for these
+  // instances.
+  //
+  // **Beta Feature**: This feature is still under development. It may be
+  // changed before final release.
+  repeated AcceleratorConfig accelerators = 8;
+
+  // Optional. Specifies the minimum cpu platform for the Instance Group.
+  // See [Cloud Dataproc&rarr;Minimum CPU Platform]
+  // (/dataproc/docs/concepts/compute/dataproc-min-cpu).
+  string min_cpu_platform = 9;
+}
+
+// Specifies the resources used to actively manage an instance group.
+message ManagedGroupConfig {
+  // Output only. The name of the Instance Template used for the Managed
+  // Instance Group.
+  string instance_template_name = 1;
+
+  // Output only. The name of the Instance Group Manager for this group.
+  string instance_group_manager_name = 2;
+}
+
+// Specifies the type and number of accelerator cards attached to the instances
+// of an instance group (see [GPUs on Compute Engine](/compute/docs/gpus/)).
+message AcceleratorConfig {
+  // Full URL, partial URI, or short name of the accelerator type resource to
+  // expose to this instance. See [Compute Engine AcceleratorTypes](
+  // /compute/docs/reference/beta/acceleratorTypes)
+  //
+  // Examples
+  // * `https://www.googleapis.com/compute/beta/projects/[project_id]/zones/us-east1-a/acceleratorTypes/nvidia-tesla-k80`
+  // * `projects/[project_id]/zones/us-east1-a/acceleratorTypes/nvidia-tesla-k80`
+  // * `nvidia-tesla-k80`
+  //
+  // **Auto Zone Exception**: If you are using the Cloud Dataproc
+  // [Auto Zone Placement](/dataproc/docs/concepts/configuring-clusters/auto-zone#using_auto_zone_placement)
+  // feature, you must use the short name of the accelerator type
+  // resource, for example, `nvidia-tesla-k80`.
+  string accelerator_type_uri = 1;
+
+  // The number of the accelerator cards of this type exposed to this instance.
+  int32 accelerator_count = 2;
+}
+
+// Specifies the config of disk options for a group of VM instances.
+message DiskConfig {
+  // Optional. Type of the boot disk (default is "pd-standard").
+  // Valid values: "pd-ssd" (Persistent Disk Solid State Drive) or
+  // "pd-standard" (Persistent Disk Hard Disk Drive).
+  string boot_disk_type = 3;
+
+  // Optional. Size in GB of the boot disk (default is 500GB).
+  int32 boot_disk_size_gb = 1;
+
+  // Optional. Number of attached SSDs, from 0 to 4 (default is 0).
+  // If SSDs are not attached, the boot disk is used to store runtime logs and
+  // [HDFS](https://hadoop.apache.org/docs/r1.2.1/hdfs_user_guide.html) data.
+  // If one or more SSDs are attached, this runtime bulk
+  // data is spread across them, and the boot disk contains only basic
+  // config and installed binaries.
+  int32 num_local_ssds = 2;
+}
+
+// Specifies the cluster auto-delete schedule configuration.
+message LifecycleConfig {
+  // Optional. The duration to keep the cluster alive while idling.
+  // Passing this threshold will cause the cluster to be
+  // deleted. Valid range: **[10m, 14d]**.
+  //
+  // Example: **"10m"**, the minimum value, to delete the
+  // cluster when it has had no jobs running for 10 minutes.
+  google.protobuf.Duration idle_delete_ttl = 1;
+
+  // Optional. Either the exact time the cluster should be deleted at or
+  // the cluster maximum age.
+  oneof ttl {
+    // Optional. The time when cluster will be auto-deleted.
+    google.protobuf.Timestamp auto_delete_time = 2;
+
+    // Optional. The lifetime duration of cluster. The cluster will be
+    // auto-deleted at the end of this period. Valid range: **[10m, 14d]**.
+    //
+    // Example: **"1d"**, to delete the cluster 1 day after its creation..
+    google.protobuf.Duration auto_delete_ttl = 3;
+  }
+}
+
+// Specifies an executable to run on a fully configured node and a
+// timeout period for executable completion.
+message NodeInitializationAction {
+  // Required. Cloud Storage URI of executable file.
+  string executable_file = 1;
+
+  // Optional. Amount of time executable has to complete. Default is
+  // 10 minutes. Cluster creation fails with an explanatory error message (the
+  // name of the executable that caused the error and the exceeded timeout
+  // period) if the executable is not completed at end of the timeout period.
+  google.protobuf.Duration execution_timeout = 2;
+}
+
+// The status of a cluster and its instances.
+message ClusterStatus {
+  // The cluster state.
+  enum State {
+    // The cluster state is unknown.
+    UNKNOWN = 0;
+
+    // The cluster is being created and set up. It is not ready for use.
+    CREATING = 1;
+
+    // The cluster is currently running and healthy. It is ready for use.
+    RUNNING = 2;
+
+    // The cluster encountered an error. It is not ready for use.
+    ERROR = 3;
+
+    // The cluster is being deleted. It cannot be used.
+    DELETING = 4;
+
+    // The cluster is being updated. It continues to accept and process jobs.
+    UPDATING = 5;
+  }
+
+  // The cluster substate.
+  enum Substate {
+    // The cluster substate is unknown.
+    UNSPECIFIED = 0;
+
+    // The cluster is known to be in an unhealthy state
+    // (for example, critical daemons are not running or HDFS capacity is
+    // exhausted).
+    //
+    // Applies to RUNNING state.
+    UNHEALTHY = 1;
+
+    // The agent-reported status is out of date (may occur if
+    // Cloud Dataproc loses communication with Agent).
+    //
+    // Applies to RUNNING state.
+    STALE_STATUS = 2;
+  }
+
+  // Output only. The cluster's state.
+  State state = 1;
+
+  // Output only. Optional details of cluster's state.
+  string detail = 2;
+
+  // Output only. Time when this state was entered.
+  google.protobuf.Timestamp state_start_time = 3;
+
+  // Output only. Additional state information that includes
+  // status reported by the agent.
+  Substate substate = 4;
+}
+
+// Specifies the selection and config of software inside the cluster.
+message SoftwareConfig {
+  // Optional. The version of software inside the cluster. It must be one of the supported
+  // [Cloud Dataproc Versions](/dataproc/docs/concepts/versioning/dataproc-versions#supported_cloud_dataproc_versions),
+  // such as "1.2" (including a subminor version, such as "1.2.29"), or the
+  // ["preview" version](/dataproc/docs/concepts/versioning/dataproc-versions#other_versions).
+  // If unspecified, it defaults to the latest version.
+  string image_version = 1;
+
+  // Optional. The properties to set on daemon config files.
+  //
+  // Property keys are specified in `prefix:property` format, such as
+  // `core:fs.defaultFS`. The following are supported prefixes
+  // and their mappings:
+  //
+  // * capacity-scheduler: `capacity-scheduler.xml`
+  // * core:   `core-site.xml`
+  // * distcp: `distcp-default.xml`
+  // * hdfs:   `hdfs-site.xml`
+  // * hive:   `hive-site.xml`
+  // * mapred: `mapred-site.xml`
+  // * pig:    `pig.properties`
+  // * spark:  `spark-defaults.conf`
+  // * yarn:   `yarn-site.xml`
+  //
+  // For more information, see
+  // [Cluster properties](/dataproc/docs/concepts/cluster-properties).
+  map<string, string> properties = 2;
+}
+
+// Contains cluster daemon metrics, such as HDFS and YARN stats.
+//
+// **Beta Feature**: This report is available for testing purposes only. It may
+// be changed before final release.
+message ClusterMetrics {
+  // The HDFS metrics.
+  map<string, int64> hdfs_metrics = 1;
+
+  // The YARN metrics.
+  map<string, int64> yarn_metrics = 2;
+}
+
+// A request to create a cluster.
+message CreateClusterRequest {
+  // Required. The ID of the Google Cloud Platform project that the cluster
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The cluster to create.
+  Cluster cluster = 2;
+
+  // Optional. A unique id used to identify the request. If the server
+  // receives two [CreateClusterRequest][google.cloud.dataproc.v1beta2.CreateClusterRequest] requests  with the same
+  // id, then the second request will be ignored and the
+  // first [google.longrunning.Operation][google.longrunning.Operation] created and stored in the backend
+  // is returned.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 4;
+}
+
+// A request to update a cluster.
+message UpdateClusterRequest {
+  // Required. The ID of the Google Cloud Platform project the
+  // cluster belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 5;
+
+  // Required. The cluster name.
+  string cluster_name = 2;
+
+  // Required. The changes to the cluster.
+  Cluster cluster = 3;
+
+  // Optional. Timeout for graceful YARN decomissioning. Graceful
+  // decommissioning allows removing nodes from the cluster without
+  // interrupting jobs in progress. Timeout specifies how long to wait for jobs
+  // in progress to finish before forcefully removing nodes (and potentially
+  // interrupting jobs). Default timeout is 0 (for forceful decommission), and
+  // the maximum allowed timeout is 1 day.
+  //
+  // Only supported on Dataproc image versions 1.2 and higher.
+  google.protobuf.Duration graceful_decommission_timeout = 6;
+
+  // Required. Specifies the path, relative to `Cluster`, of
+  // the field to update. For example, to change the number of workers
+  // in a cluster to 5, the `update_mask` parameter would be
+  // specified as `config.worker_config.num_instances`,
+  // and the `PATCH` request body would specify the new value, as follows:
+  //
+  //     {
+  //       "config":{
+  //         "workerConfig":{
+  //           "numInstances":"5"
+  //         }
+  //       }
+  //     }
+  //
+  // Similarly, to change the number of preemptible workers in a cluster to 5, the
+  // `update_mask` parameter would be `config.secondary_worker_config.num_instances`,
+  // and the `PATCH` request body would be set as follows:
+  //
+  //     {
+  //       "config":{
+  //         "secondaryWorkerConfig":{
+  //           "numInstances":"5"
+  //         }
+  //       }
+  //     }
+  // <strong>Note:</strong> currently only the following fields can be updated:
+  //
+  // <table>
+  // <tr>
+  // <td><strong>Mask</strong></td><td><strong>Purpose</strong></td>
+  // </tr>
+  // <tr>
+  // <td>labels</td><td>Updates labels</td>
+  // </tr>
+  // <tr>
+  // <td>config.worker_config.num_instances</td><td>Resize primary worker group</td>
+  // </tr>
+  // <tr>
+  // <td>config.secondary_worker_config.num_instances</td><td>Resize secondary worker group</td>
+  // </tr>
+  // <tr>
+  // <td>config.lifecycle_config.auto_delete_ttl</td><td>Reset MAX TTL duration</td>
+  // </tr>
+  // <tr>
+  // <td>config.lifecycle_config.auto_delete_time</td><td>Update MAX TTL deletion timestamp</td>
+  // </tr>
+  // <tr>
+  // <td>config.lifecycle_config.idle_delete_ttl</td><td>Update Idle TTL duration</td>
+  // </tr>
+  // </table>
+  google.protobuf.FieldMask update_mask = 4;
+
+  // Optional. A unique id used to identify the request. If the server
+  // receives two [UpdateClusterRequest][google.cloud.dataproc.v1beta2.UpdateClusterRequest] requests  with the same
+  // id, then the second request will be ignored and the
+  // first [google.longrunning.Operation][google.longrunning.Operation] created and stored in the
+  // backend is returned.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 7;
+}
+
+// A request to delete a cluster.
+message DeleteClusterRequest {
+  // Required. The ID of the Google Cloud Platform project that the cluster
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The cluster name.
+  string cluster_name = 2;
+
+  // Optional. Specifying the `cluster_uuid` means the RPC should fail
+  // (with error NOT_FOUND) if cluster with specified UUID does not exist.
+  string cluster_uuid = 4;
+
+  // Optional. A unique id used to identify the request. If the server
+  // receives two [DeleteClusterRequest][google.cloud.dataproc.v1beta2.DeleteClusterRequest] requests  with the same
+  // id, then the second request will be ignored and the
+  // first [google.longrunning.Operation][google.longrunning.Operation] created and stored in the
+  // backend is returned.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 5;
+}
+
+// Request to get the resource representation for a cluster in a project.
+message GetClusterRequest {
+  // Required. The ID of the Google Cloud Platform project that the cluster
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The cluster name.
+  string cluster_name = 2;
+}
+
+// A request to list the clusters in a project.
+message ListClustersRequest {
+  // Required. The ID of the Google Cloud Platform project that the cluster
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 4;
+
+  // Optional. A filter constraining the clusters to list. Filters are
+  // case-sensitive and have the following syntax:
+  //
+  // field = value [AND [field = value]] ...
+  //
+  // where **field** is one of `status.state`, `clusterName`, or `labels.[KEY]`,
+  // and `[KEY]` is a label key. **value** can be `*` to match all values.
+  // `status.state` can be one of the following: `ACTIVE`, `INACTIVE`,
+  // `CREATING`, `RUNNING`, `ERROR`, `DELETING`, or `UPDATING`. `ACTIVE`
+  // contains the `CREATING`, `UPDATING`, and `RUNNING` states. `INACTIVE`
+  // contains the `DELETING` and `ERROR` states.
+  // `clusterName` is the name of the cluster provided at creation time.
+  // Only the logical `AND` operator is supported; space-separated items are
+  // treated as having an implicit `AND` operator.
+  //
+  // Example filter:
+  //
+  // status.state = ACTIVE AND clusterName = mycluster
+  // AND labels.env = staging AND labels.starred = *
+  string filter = 5;
+
+  // Optional. The standard List page size.
+  int32 page_size = 2;
+
+  // Optional. The standard List page token.
+  string page_token = 3;
+}
+
+// The list of all clusters in a project.
+message ListClustersResponse {
+  // Output only. The clusters in the project.
+  repeated Cluster clusters = 1;
+
+  // Output only. This token is included in the response if there are more
+  // results to fetch. To fetch additional results, provide this value as the
+  // `page_token` in a subsequent <code>ListClustersRequest</code>.
+  string next_page_token = 2;
+}
+
+// A request to collect cluster diagnostic information.
+message DiagnoseClusterRequest {
+  // Required. The ID of the Google Cloud Platform project that the cluster
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The cluster name.
+  string cluster_name = 2;
+}
+
+// The location of diagnostic output.
+message DiagnoseClusterResults {
+  // Output only. The Cloud Storage URI of the diagnostic output.
+  // The output report is a plain text file with a summary of collected
+  // diagnostics.
+  string output_uri = 1;
+}
diff --git a/dataproc/google/cloud/dataproc_v1/proto/jobs.proto b/dataproc/google/cloud/dataproc_v1/proto/jobs.proto
new file mode 100644
index 000000000000..7aff5f462ad1
--- /dev/null
+++ b/dataproc/google/cloud/dataproc_v1/proto/jobs.proto
@@ -0,0 +1,777 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.dataproc.v1beta2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2;dataproc";
+option java_multiple_files = true;
+option java_outer_classname = "JobsProto";
+option java_package = "com.google.cloud.dataproc.v1beta2";
+
+
+// The JobController provides methods to manage jobs.
+service JobController {
+  // Submits a job to a cluster.
+  rpc SubmitJob(SubmitJobRequest) returns (Job) {
+    option (google.api.http) = {
+      post: "/v1beta2/projects/{project_id}/regions/{region}/jobs:submit"
+      body: "*"
+    };
+  }
+
+  // Gets the resource representation for a job in a project.
+  rpc GetJob(GetJobRequest) returns (Job) {
+    option (google.api.http) = {
+      get: "/v1beta2/projects/{project_id}/regions/{region}/jobs/{job_id}"
+    };
+  }
+
+  // Lists regions/{region}/jobs in a project.
+  rpc ListJobs(ListJobsRequest) returns (ListJobsResponse) {
+    option (google.api.http) = {
+      get: "/v1beta2/projects/{project_id}/regions/{region}/jobs"
+    };
+  }
+
+  // Updates a job in a project.
+  rpc UpdateJob(UpdateJobRequest) returns (Job) {
+    option (google.api.http) = {
+      patch: "/v1beta2/projects/{project_id}/regions/{region}/jobs/{job_id}"
+      body: "job"
+    };
+  }
+
+  // Starts a job cancellation request. To access the job resource
+  // after cancellation, call
+  // [regions/{region}/jobs.list](/dataproc/docs/reference/rest/v1beta2/projects.regions.jobs/list) or
+  // [regions/{region}/jobs.get](/dataproc/docs/reference/rest/v1beta2/projects.regions.jobs/get).
+  rpc CancelJob(CancelJobRequest) returns (Job) {
+    option (google.api.http) = {
+      post: "/v1beta2/projects/{project_id}/regions/{region}/jobs/{job_id}:cancel"
+      body: "*"
+    };
+  }
+
+  // Deletes the job from the project. If the job is active, the delete fails,
+  // and the response returns `FAILED_PRECONDITION`.
+  rpc DeleteJob(DeleteJobRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1beta2/projects/{project_id}/regions/{region}/jobs/{job_id}"
+    };
+  }
+}
+
+// The runtime logging config of the job.
+message LoggingConfig {
+  // The Log4j level for job execution. When running an
+  // [Apache Hive](http://hive.apache.org/) job, Cloud
+  // Dataproc configures the Hive client to an equivalent verbosity level.
+  enum Level {
+    // Level is unspecified. Use default level for log4j.
+    LEVEL_UNSPECIFIED = 0;
+
+    // Use ALL level for log4j.
+    ALL = 1;
+
+    // Use TRACE level for log4j.
+    TRACE = 2;
+
+    // Use DEBUG level for log4j.
+    DEBUG = 3;
+
+    // Use INFO level for log4j.
+    INFO = 4;
+
+    // Use WARN level for log4j.
+    WARN = 5;
+
+    // Use ERROR level for log4j.
+    ERROR = 6;
+
+    // Use FATAL level for log4j.
+    FATAL = 7;
+
+    // Turn off log4j.
+    OFF = 8;
+  }
+
+  // The per-package log levels for the driver. This may include
+  // "root" package name to configure rootLogger.
+  // Examples:
+  //   'com.google = FATAL', 'root = INFO', 'org.apache = DEBUG'
+  map<string, Level> driver_log_levels = 2;
+}
+
+// A Cloud Dataproc job for running
+// [Apache Hadoop MapReduce](https://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html)
+// jobs on [Apache Hadoop YARN](https://hadoop.apache.org/docs/r2.7.1/hadoop-yarn/hadoop-yarn-site/YARN.html).
+message HadoopJob {
+  // Required. Indicates the location of the driver's main class. Specify
+  // either the jar file that contains the main class or the main class name.
+  // To specify both, add the jar file to `jar_file_uris`, and then specify
+  // the main class name in this property.
+  oneof driver {
+    // The HCFS URI of the jar file containing the main class.
+    // Examples:
+    //     'gs://foo-bucket/analytics-binaries/extract-useful-metrics-mr.jar'
+    //     'hdfs:/tmp/test-samples/custom-wordcount.jar'
+    //     'file:///home/usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples.jar'
+    string main_jar_file_uri = 1;
+
+    // The name of the driver's main class. The jar file containing the class
+    // must be in the default CLASSPATH or specified in `jar_file_uris`.
+    string main_class = 2;
+  }
+
+  // Optional. The arguments to pass to the driver. Do not
+  // include arguments, such as `-libjars` or `-Dfoo=bar`, that can be set as job
+  // properties, since a collision may occur that causes an incorrect job
+  // submission.
+  repeated string args = 3;
+
+  // Optional. Jar file URIs to add to the CLASSPATHs of the
+  // Hadoop driver and tasks.
+  repeated string jar_file_uris = 4;
+
+  // Optional. HCFS (Hadoop Compatible Filesystem) URIs of files to be copied
+  // to the working directory of Hadoop drivers and distributed tasks. Useful
+  // for naively parallel tasks.
+  repeated string file_uris = 5;
+
+  // Optional. HCFS URIs of archives to be extracted in the working directory of
+  // Hadoop drivers and tasks. Supported file types:
+  // .jar, .tar, .tar.gz, .tgz, or .zip.
+  repeated string archive_uris = 6;
+
+  // Optional. A mapping of property names to values, used to configure Hadoop.
+  // Properties that conflict with values set by the Cloud Dataproc API may be
+  // overwritten. Can include properties set in /etc/hadoop/conf/*-site and
+  // classes in user code.
+  map<string, string> properties = 7;
+
+  // Optional. The runtime log config for job execution.
+  LoggingConfig logging_config = 8;
+}
+
+// A Cloud Dataproc job for running [Apache Spark](http://spark.apache.org/)
+// applications on YARN.
+message SparkJob {
+  // Required. The specification of the main method to call to drive the job.
+  // Specify either the jar file that contains the main class or the main class
+  // name. To pass both a main jar and a main class in that jar, add the jar to
+  // `CommonJob.jar_file_uris`, and then specify the main class name in `main_class`.
+  oneof driver {
+    // The HCFS URI of the jar file that contains the main class.
+    string main_jar_file_uri = 1;
+
+    // The name of the driver's main class. The jar file that contains the class
+    // must be in the default CLASSPATH or specified in `jar_file_uris`.
+    string main_class = 2;
+  }
+
+  // Optional. The arguments to pass to the driver. Do not include arguments,
+  // such as `--conf`, that can be set as job properties, since a collision may
+  // occur that causes an incorrect job submission.
+  repeated string args = 3;
+
+  // Optional. HCFS URIs of jar files to add to the CLASSPATHs of the
+  // Spark driver and tasks.
+  repeated string jar_file_uris = 4;
+
+  // Optional. HCFS URIs of files to be copied to the working directory of
+  // Spark drivers and distributed tasks. Useful for naively parallel tasks.
+  repeated string file_uris = 5;
+
+  // Optional. HCFS URIs of archives to be extracted in the working directory
+  // of Spark drivers and tasks. Supported file types:
+  // .jar, .tar, .tar.gz, .tgz, and .zip.
+  repeated string archive_uris = 6;
+
+  // Optional. A mapping of property names to values, used to configure Spark.
+  // Properties that conflict with values set by the Cloud Dataproc API may be
+  // overwritten. Can include properties set in
+  // /etc/spark/conf/spark-defaults.conf and classes in user code.
+  map<string, string> properties = 7;
+
+  // Optional. The runtime log config for job execution.
+  LoggingConfig logging_config = 8;
+}
+
+// A Cloud Dataproc job for running
+// [Apache PySpark](https://spark.apache.org/docs/0.9.0/python-programming-guide.html)
+// applications on YARN.
+message PySparkJob {
+  // Required. The HCFS URI of the main Python file to use as the driver. Must
+  // be a .py file.
+  string main_python_file_uri = 1;
+
+  // Optional. The arguments to pass to the driver.  Do not include arguments,
+  // such as `--conf`, that can be set as job properties, since a collision may
+  // occur that causes an incorrect job submission.
+  repeated string args = 2;
+
+  // Optional. HCFS file URIs of Python files to pass to the PySpark
+  // framework. Supported file types: .py, .egg, and .zip.
+  repeated string python_file_uris = 3;
+
+  // Optional. HCFS URIs of jar files to add to the CLASSPATHs of the
+  // Python driver and tasks.
+  repeated string jar_file_uris = 4;
+
+  // Optional. HCFS URIs of files to be copied to the working directory of
+  // Python drivers and distributed tasks. Useful for naively parallel tasks.
+  repeated string file_uris = 5;
+
+  // Optional. HCFS URIs of archives to be extracted in the working directory of
+  // .jar, .tar, .tar.gz, .tgz, and .zip.
+  repeated string archive_uris = 6;
+
+  // Optional. A mapping of property names to values, used to configure PySpark.
+  // Properties that conflict with values set by the Cloud Dataproc API may be
+  // overwritten. Can include properties set in
+  // /etc/spark/conf/spark-defaults.conf and classes in user code.
+  map<string, string> properties = 7;
+
+  // Optional. The runtime log config for job execution.
+  LoggingConfig logging_config = 8;
+}
+
+// A list of queries to run on a cluster.
+message QueryList {
+  // Required. The queries to execute. You do not need to terminate a query
+  // with a semicolon. Multiple queries can be specified in one string
+  // by separating each with a semicolon. Here is an example of an Cloud
+  // Dataproc API snippet that uses a QueryList to specify a HiveJob:
+  //
+  //     "hiveJob": {
+  //       "queryList": {
+  //         "queries": [
+  //           "query1",
+  //           "query2",
+  //           "query3;query4",
+  //         ]
+  //       }
+  //     }
+  repeated string queries = 1;
+}
+
+// A Cloud Dataproc job for running [Apache Hive](https://hive.apache.org/)
+// queries on YARN.
+message HiveJob {
+  // Required. The sequence of Hive queries to execute, specified as either
+  // an HCFS file URI or a list of queries.
+  oneof queries {
+    // The HCFS URI of the script that contains Hive queries.
+    string query_file_uri = 1;
+
+    // A list of queries.
+    QueryList query_list = 2;
+  }
+
+  // Optional. Whether to continue executing queries if a query fails.
+  // The default value is `false`. Setting to `true` can be useful when executing
+  // independent parallel queries.
+  bool continue_on_failure = 3;
+
+  // Optional. Mapping of query variable names to values (equivalent to the
+  // Hive command: `SET name="value";`).
+  map<string, string> script_variables = 4;
+
+  // Optional. A mapping of property names and values, used to configure Hive.
+  // Properties that conflict with values set by the Cloud Dataproc API may be
+  // overwritten. Can include properties set in /etc/hadoop/conf/*-site.xml,
+  // /etc/hive/conf/hive-site.xml, and classes in user code.
+  map<string, string> properties = 5;
+
+  // Optional. HCFS URIs of jar files to add to the CLASSPATH of the
+  // Hive server and Hadoop MapReduce (MR) tasks. Can contain Hive SerDes
+  // and UDFs.
+  repeated string jar_file_uris = 6;
+}
+
+// A Cloud Dataproc job for running [Apache Spark SQL](http://spark.apache.org/sql/)
+// queries.
+message SparkSqlJob {
+  // Required. The sequence of Spark SQL queries to execute, specified as
+  // either an HCFS file URI or as a list of queries.
+  oneof queries {
+    // The HCFS URI of the script that contains SQL queries.
+    string query_file_uri = 1;
+
+    // A list of queries.
+    QueryList query_list = 2;
+  }
+
+  // Optional. Mapping of query variable names to values (equivalent to the
+  // Spark SQL command: SET `name="value";`).
+  map<string, string> script_variables = 3;
+
+  // Optional. A mapping of property names to values, used to configure
+  // Spark SQL's SparkConf. Properties that conflict with values set by the
+  // Cloud Dataproc API may be overwritten.
+  map<string, string> properties = 4;
+
+  // Optional. HCFS URIs of jar files to be added to the Spark CLASSPATH.
+  repeated string jar_file_uris = 56;
+
+  // Optional. The runtime log config for job execution.
+  LoggingConfig logging_config = 6;
+}
+
+// A Cloud Dataproc job for running [Apache Pig](https://pig.apache.org/)
+// queries on YARN.
+message PigJob {
+  // Required. The sequence of Pig queries to execute, specified as an HCFS
+  // file URI or a list of queries.
+  oneof queries {
+    // The HCFS URI of the script that contains the Pig queries.
+    string query_file_uri = 1;
+
+    // A list of queries.
+    QueryList query_list = 2;
+  }
+
+  // Optional. Whether to continue executing queries if a query fails.
+  // The default value is `false`. Setting to `true` can be useful when executing
+  // independent parallel queries.
+  bool continue_on_failure = 3;
+
+  // Optional. Mapping of query variable names to values (equivalent to the Pig
+  // command: `name=[value]`).
+  map<string, string> script_variables = 4;
+
+  // Optional. A mapping of property names to values, used to configure Pig.
+  // Properties that conflict with values set by the Cloud Dataproc API may be
+  // overwritten. Can include properties set in /etc/hadoop/conf/*-site.xml,
+  // /etc/pig/conf/pig.properties, and classes in user code.
+  map<string, string> properties = 5;
+
+  // Optional. HCFS URIs of jar files to add to the CLASSPATH of
+  // the Pig Client and Hadoop MapReduce (MR) tasks. Can contain Pig UDFs.
+  repeated string jar_file_uris = 6;
+
+  // Optional. The runtime log config for job execution.
+  LoggingConfig logging_config = 7;
+}
+
+// Cloud Dataproc job config.
+message JobPlacement {
+  // Required. The name of the cluster where the job will be submitted.
+  string cluster_name = 1;
+
+  // Output only. A cluster UUID generated by the Cloud Dataproc service when
+  // the job is submitted.
+  string cluster_uuid = 2;
+}
+
+// Cloud Dataproc job status.
+message JobStatus {
+  // The job state.
+  enum State {
+    // The job state is unknown.
+    STATE_UNSPECIFIED = 0;
+
+    // The job is pending; it has been submitted, but is not yet running.
+    PENDING = 1;
+
+    // Job has been received by the service and completed initial setup;
+    // it will soon be submitted to the cluster.
+    SETUP_DONE = 8;
+
+    // The job is running on the cluster.
+    RUNNING = 2;
+
+    // A CancelJob request has been received, but is pending.
+    CANCEL_PENDING = 3;
+
+    // Transient in-flight resources have been canceled, and the request to
+    // cancel the running job has been issued to the cluster.
+    CANCEL_STARTED = 7;
+
+    // The job cancellation was successful.
+    CANCELLED = 4;
+
+    // The job has completed successfully.
+    DONE = 5;
+
+    // The job has completed, but encountered an error.
+    ERROR = 6;
+
+    // Job attempt has failed. The detail field contains failure details for
+    // this attempt.
+    //
+    // Applies to restartable jobs only.
+    ATTEMPT_FAILURE = 9;
+  }
+
+  // The job substate.
+  enum Substate {
+    // The job substate is unknown.
+    UNSPECIFIED = 0;
+
+    // The Job is submitted to the agent.
+    //
+    // Applies to RUNNING state.
+    SUBMITTED = 1;
+
+    // The Job has been received and is awaiting execution (it may be waiting
+    // for a condition to be met). See the "details" field for the reason for
+    // the delay.
+    //
+    // Applies to RUNNING state.
+    QUEUED = 2;
+
+    // The agent-reported status is out of date, which may be caused by a
+    // loss of communication between the agent and Cloud Dataproc. If the
+    // agent does not send a timely update, the job will fail.
+    //
+    // Applies to RUNNING state.
+    STALE_STATUS = 3;
+  }
+
+  // Output only. A state message specifying the overall job state.
+  State state = 1;
+
+  // Output only. Optional job state details, such as an error
+  // description if the state is <code>ERROR</code>.
+  string details = 2;
+
+  // Output only. The time when this state was entered.
+  google.protobuf.Timestamp state_start_time = 6;
+
+  // Output only. Additional state information, which includes
+  // status reported by the agent.
+  Substate substate = 7;
+}
+
+// Encapsulates the full scoping used to reference a job.
+message JobReference {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Optional. The job ID, which must be unique within the project. The job ID
+  // is generated by the server upon job submission or provided by the user as a
+  // means to perform retries without creating duplicate jobs. The ID must
+  // contain only letters (a-z, A-Z), numbers (0-9), underscores (_), or
+  // hyphens (-). The maximum length is 100 characters.
+  string job_id = 2;
+}
+
+// A YARN application created by a job. Application information is a subset of
+// <code>org.apache.hadoop.yarn.proto.YarnProtos.ApplicationReportProto</code>.
+//
+// **Beta Feature**: This report is available for testing purposes only. It may
+// be changed before final release.
+message YarnApplication {
+  // The application state, corresponding to
+  // <code>YarnProtos.YarnApplicationStateProto</code>.
+  enum State {
+    // Status is unspecified.
+    STATE_UNSPECIFIED = 0;
+
+    // Status is NEW.
+    NEW = 1;
+
+    // Status is NEW_SAVING.
+    NEW_SAVING = 2;
+
+    // Status is SUBMITTED.
+    SUBMITTED = 3;
+
+    // Status is ACCEPTED.
+    ACCEPTED = 4;
+
+    // Status is RUNNING.
+    RUNNING = 5;
+
+    // Status is FINISHED.
+    FINISHED = 6;
+
+    // Status is FAILED.
+    FAILED = 7;
+
+    // Status is KILLED.
+    KILLED = 8;
+  }
+
+  // Required. The application name.
+  string name = 1;
+
+  // Required. The application state.
+  State state = 2;
+
+  // Required. The numerical progress of the application, from 1 to 100.
+  float progress = 3;
+
+  // Optional. The HTTP URL of the ApplicationMaster, HistoryServer, or
+  // TimelineServer that provides application-specific information. The URL uses
+  // the internal hostname, and requires a proxy server for resolution and,
+  // possibly, access.
+  string tracking_url = 4;
+}
+
+// A Cloud Dataproc job resource.
+message Job {
+  // Optional. The fully qualified reference to the job, which can be used to
+  // obtain the equivalent REST path of the job resource. If this property
+  // is not specified when a job is created, the server generates a
+  // <code>job_id</code>.
+  JobReference reference = 1;
+
+  // Required. Job information, including how, when, and where to
+  // run the job.
+  JobPlacement placement = 2;
+
+  // Required. The application/framework-specific portion of the job.
+  oneof type_job {
+    // Job is a Hadoop job.
+    HadoopJob hadoop_job = 3;
+
+    // Job is a Spark job.
+    SparkJob spark_job = 4;
+
+    // Job is a Pyspark job.
+    PySparkJob pyspark_job = 5;
+
+    // Job is a Hive job.
+    HiveJob hive_job = 6;
+
+    // Job is a Pig job.
+    PigJob pig_job = 7;
+
+    // Job is a SparkSql job.
+    SparkSqlJob spark_sql_job = 12;
+  }
+
+  // Output only. The job status. Additional application-specific
+  // status information may be contained in the <code>type_job</code>
+  // and <code>yarn_applications</code> fields.
+  JobStatus status = 8;
+
+  // Output only. The previous job status.
+  repeated JobStatus status_history = 13;
+
+  // Output only. The collection of YARN applications spun up by this job.
+  //
+  // **Beta** Feature: This report is available for testing purposes only. It may
+  // be changed before final release.
+  repeated YarnApplication yarn_applications = 9;
+
+  // Output only. The email address of the user submitting the job. For jobs
+  // submitted on the cluster, the address is <code>username@hostname</code>.
+  string submitted_by = 10;
+
+  // Output only. A URI pointing to the location of the stdout of the job's
+  // driver program.
+  string driver_output_resource_uri = 17;
+
+  // Output only. If present, the location of miscellaneous control files
+  // which may be used as part of job setup and handling. If not present,
+  // control files may be placed in the same location as `driver_output_uri`.
+  string driver_control_files_uri = 15;
+
+  // Optional. The labels to associate with this job.
+  // Label **keys** must contain 1 to 63 characters, and must conform to
+  // [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  // Label **values** may be empty, but, if present, must contain 1 to 63
+  // characters, and must conform to [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  // No more than 32 labels can be associated with a job.
+  map<string, string> labels = 18;
+
+  // Optional. Job scheduling configuration.
+  JobScheduling scheduling = 20;
+
+  // Output only. A UUID that uniquely identifies a job within the project
+  // over time. This is in contrast to a user-settable reference.job_id that
+  // may be reused over time.
+  string job_uuid = 22;
+}
+
+// Job scheduling options.
+message JobScheduling {
+  // Optional. Maximum number of times per hour a driver may be restarted as
+  // a result of driver terminating with non-zero code before job is
+  // reported failed.
+  //
+  // A job may be reported as thrashing if driver exits with non-zero code
+  // 4 times within 10 minute window.
+  //
+  // Maximum value is 10.
+  int32 max_failures_per_hour = 1;
+}
+
+// A request to submit a job.
+message SubmitJobRequest {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The job resource.
+  Job job = 2;
+
+  // Optional. A unique id used to identify the request. If the server
+  // receives two [SubmitJobRequest][google.cloud.dataproc.v1beta2.SubmitJobRequest] requests  with the same
+  // id, then the second request will be ignored and the
+  // first [Job][google.cloud.dataproc.v1beta2.Job] created and stored in the backend
+  // is returned.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 4;
+}
+
+// A request to get the resource representation for a job in a project.
+message GetJobRequest {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The job ID.
+  string job_id = 2;
+}
+
+// A request to list jobs in a project.
+message ListJobsRequest {
+  // A matcher that specifies categories of job states.
+  enum JobStateMatcher {
+    // Match all jobs, regardless of state.
+    ALL = 0;
+
+    // Only match jobs in non-terminal states: PENDING, RUNNING, or
+    // CANCEL_PENDING.
+    ACTIVE = 1;
+
+    // Only match jobs in terminal states: CANCELLED, DONE, or ERROR.
+    NON_ACTIVE = 2;
+  }
+
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 6;
+
+  // Optional. The number of results to return in each response.
+  int32 page_size = 2;
+
+  // Optional. The page token, returned by a previous call, to request the
+  // next page of results.
+  string page_token = 3;
+
+  // Optional. If set, the returned jobs list includes only jobs that were
+  // submitted to the named cluster.
+  string cluster_name = 4;
+
+  // Optional. Specifies enumerated categories of jobs to list.
+  // (default = match ALL jobs).
+  //
+  // If `filter` is provided, `jobStateMatcher` will be ignored.
+  JobStateMatcher job_state_matcher = 5;
+
+  // Optional. A filter constraining the jobs to list. Filters are
+  // case-sensitive and have the following syntax:
+  //
+  // [field = value] AND [field [= value]] ...
+  //
+  // where **field** is `status.state` or `labels.[KEY]`, and `[KEY]` is a label
+  // key. **value** can be `*` to match all values.
+  // `status.state` can be either `ACTIVE` or `NON_ACTIVE`.
+  // Only the logical `AND` operator is supported; space-separated items are
+  // treated as having an implicit `AND` operator.
+  //
+  // Example filter:
+  //
+  // status.state = ACTIVE AND labels.env = staging AND labels.starred = *
+  string filter = 7;
+}
+
+// A request to update a job.
+message UpdateJobRequest {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 2;
+
+  // Required. The job ID.
+  string job_id = 3;
+
+  // Required. The changes to the job.
+  Job job = 4;
+
+  // Required. Specifies the path, relative to <code>Job</code>, of
+  // the field to update. For example, to update the labels of a Job the
+  // <code>update_mask</code> parameter would be specified as
+  // <code>labels</code>, and the `PATCH` request body would specify the new
+  // value. <strong>Note:</strong> Currently, <code>labels</code> is the only
+  // field that can be updated.
+  google.protobuf.FieldMask update_mask = 5;
+}
+
+// A list of jobs in a project.
+message ListJobsResponse {
+  // Output only. Jobs list.
+  repeated Job jobs = 1;
+
+  // Optional. This token is included in the response if there are more results
+  // to fetch. To fetch additional results, provide this value as the
+  // `page_token` in a subsequent <code>ListJobsRequest</code>.
+  string next_page_token = 2;
+}
+
+// A request to cancel a job.
+message CancelJobRequest {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The job ID.
+  string job_id = 2;
+}
+
+// A request to delete a job.
+message DeleteJobRequest {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The job ID.
+  string job_id = 2;
+}
diff --git a/dataproc/google/cloud/dataproc_v1/proto/operations.proto b/dataproc/google/cloud/dataproc_v1/proto/operations.proto
new file mode 100644
index 000000000000..717410832ff6
--- /dev/null
+++ b/dataproc/google/cloud/dataproc_v1/proto/operations.proto
@@ -0,0 +1,84 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.dataproc.v1beta2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2;dataproc";
+option java_multiple_files = true;
+option java_outer_classname = "OperationsProto";
+option java_package = "com.google.cloud.dataproc.v1beta2";
+
+
+// The status of the operation.
+message ClusterOperationStatus {
+  // The operation state.
+  enum State {
+    // Unused.
+    UNKNOWN = 0;
+
+    // The operation has been created.
+    PENDING = 1;
+
+    // The operation is running.
+    RUNNING = 2;
+
+    // The operation is done; either cancelled or completed.
+    DONE = 3;
+  }
+
+  // Output only. A message containing the operation state.
+  State state = 1;
+
+  // Output only. A message containing the detailed operation state.
+  string inner_state = 2;
+
+  // Output only. A message containing any operation metadata details.
+  string details = 3;
+
+  // Output only. The time this state was entered.
+  google.protobuf.Timestamp state_start_time = 4;
+}
+
+// Metadata describing the operation.
+message ClusterOperationMetadata {
+  // Output only. Name of the cluster for the operation.
+  string cluster_name = 7;
+
+  // Output only. Cluster UUID for the operation.
+  string cluster_uuid = 8;
+
+  // Output only. Current operation status.
+  ClusterOperationStatus status = 9;
+
+  // Output only. The previous operation status.
+  repeated ClusterOperationStatus status_history = 10;
+
+  // Output only. The operation type.
+  string operation_type = 11;
+
+  // Output only. Short description of operation.
+  string description = 12;
+
+  // Output only. Labels associated with the operation
+  map<string, string> labels = 13;
+
+  // Output only. Errors encountered during operation execution.
+  repeated string warnings = 14;
+}
diff --git a/dataproc/google/cloud/dataproc_v1/proto/shared.proto b/dataproc/google/cloud/dataproc_v1/proto/shared.proto
new file mode 100644
index 000000000000..8d2f5e62834c
--- /dev/null
+++ b/dataproc/google/cloud/dataproc_v1/proto/shared.proto
@@ -0,0 +1,26 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.dataproc.v1beta2;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2;dataproc";
+option java_multiple_files = true;
+option java_outer_classname = "SharedProto";
+option java_package = "com.google.cloud.dataproc.v1beta2";
+
diff --git a/dataproc/google/cloud/dataproc_v1/proto/workflow_templates.proto b/dataproc/google/cloud/dataproc_v1/proto/workflow_templates.proto
new file mode 100644
index 000000000000..982f874d63b1
--- /dev/null
+++ b/dataproc/google/cloud/dataproc_v1/proto/workflow_templates.proto
@@ -0,0 +1,667 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.dataproc.v1beta2;
+
+import "google/api/annotations.proto";
+import "google/cloud/dataproc/v1beta2/clusters.proto";
+import "google/cloud/dataproc/v1beta2/jobs.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2;dataproc";
+option java_multiple_files = true;
+option java_outer_classname = "WorkflowTemplatesProto";
+option java_package = "com.google.cloud.dataproc.v1beta2";
+
+
+// The API interface for managing Workflow Templates in the
+// Cloud Dataproc API.
+service WorkflowTemplateService {
+  // Creates new workflow template.
+  rpc CreateWorkflowTemplate(CreateWorkflowTemplateRequest) returns (WorkflowTemplate) {
+    option (google.api.http) = {
+      post: "/v1beta2/{parent=projects/*/regions/*}/workflowTemplates"
+      body: "template"
+      additional_bindings {
+        post: "/v1beta2/{parent=projects/*/locations/*}/workflowTemplates"
+        body: "template"
+      }
+    };
+  }
+
+  // Retrieves the latest workflow template.
+  //
+  // Can retrieve previously instantiated template by specifying optional
+  // version parameter.
+  rpc GetWorkflowTemplate(GetWorkflowTemplateRequest) returns (WorkflowTemplate) {
+    option (google.api.http) = {
+      get: "/v1beta2/{name=projects/*/regions/*/workflowTemplates/*}"
+      additional_bindings {
+        get: "/v1beta2/{name=projects/*/locations/*/workflowTemplates/*}"
+      }
+    };
+  }
+
+  // Instantiates a template and begins execution.
+  //
+  // The returned Operation can be used to track execution of
+  // workflow by polling
+  // [operations.get][google.longrunning.Operations.GetOperation].
+  // The Operation will complete when entire workflow is finished.
+  //
+  // The running workflow can be aborted via
+  // [operations.cancel][google.longrunning.Operations.CancelOperation].
+  // This will cause any inflight jobs to be cancelled and workflow-owned
+  // clusters to be deleted.
+  //
+  // The [Operation.metadata][google.longrunning.Operation.metadata] will be
+  // [WorkflowMetadata][google.cloud.dataproc.v1beta2.WorkflowMetadata].
+  //
+  // On successful completion,
+  // [Operation.response][google.longrunning.Operation.response] will be
+  // [Empty][google.protobuf.Empty].
+  rpc InstantiateWorkflowTemplate(InstantiateWorkflowTemplateRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta2/{name=projects/*/regions/*/workflowTemplates/*}:instantiate"
+      body: "*"
+      additional_bindings {
+        post: "/v1beta2/{name=projects/*/locations/*/workflowTemplates/*}:instantiate"
+        body: "*"
+      }
+    };
+  }
+
+  // Instantiates a template and begins execution.
+  //
+  // This method is equivalent to executing the sequence
+  // [CreateWorkflowTemplate][google.cloud.dataproc.v1beta2.WorkflowTemplateService.CreateWorkflowTemplate], [InstantiateWorkflowTemplate][google.cloud.dataproc.v1beta2.WorkflowTemplateService.InstantiateWorkflowTemplate],
+  // [DeleteWorkflowTemplate][google.cloud.dataproc.v1beta2.WorkflowTemplateService.DeleteWorkflowTemplate].
+  //
+  // The returned Operation can be used to track execution of
+  // workflow by polling
+  // [operations.get][google.longrunning.Operations.GetOperation].
+  // The Operation will complete when entire workflow is finished.
+  //
+  // The running workflow can be aborted via
+  // [operations.cancel][google.longrunning.Operations.CancelOperation].
+  // This will cause any inflight jobs to be cancelled and workflow-owned
+  // clusters to be deleted.
+  //
+  // The [Operation.metadata][google.longrunning.Operation.metadata] will be
+  // [WorkflowMetadata][google.cloud.dataproc.v1beta2.WorkflowMetadata].
+  //
+  // On successful completion,
+  // [Operation.response][google.longrunning.Operation.response] will be
+  // [Empty][google.protobuf.Empty].
+  rpc InstantiateInlineWorkflowTemplate(InstantiateInlineWorkflowTemplateRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta2/{parent=projects/*/locations/*}/workflowTemplates:instantiateInline"
+      body: "template"
+      additional_bindings {
+        post: "/v1beta2/{parent=projects/*/regions/*}/workflowTemplates:instantiateInline"
+        body: "template"
+      }
+    };
+  }
+
+  // Updates (replaces) workflow template. The updated template
+  // must contain version that matches the current server version.
+  rpc UpdateWorkflowTemplate(UpdateWorkflowTemplateRequest) returns (WorkflowTemplate) {
+    option (google.api.http) = {
+      put: "/v1beta2/{template.name=projects/*/regions/*/workflowTemplates/*}"
+      body: "template"
+      additional_bindings {
+        put: "/v1beta2/{template.name=projects/*/locations/*/workflowTemplates/*}"
+        body: "template"
+      }
+    };
+  }
+
+  // Lists workflows that match the specified filter in the request.
+  rpc ListWorkflowTemplates(ListWorkflowTemplatesRequest) returns (ListWorkflowTemplatesResponse) {
+    option (google.api.http) = {
+      get: "/v1beta2/{parent=projects/*/regions/*}/workflowTemplates"
+      additional_bindings {
+        get: "/v1beta2/{parent=projects/*/locations/*}/workflowTemplates"
+      }
+    };
+  }
+
+  // Deletes a workflow template. It does not cancel in-progress workflows.
+  rpc DeleteWorkflowTemplate(DeleteWorkflowTemplateRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1beta2/{name=projects/*/regions/*/workflowTemplates/*}"
+      additional_bindings {
+        delete: "/v1beta2/{name=projects/*/locations/*/workflowTemplates/*}"
+      }
+    };
+  }
+}
+
+// A Cloud Dataproc workflow template resource.
+message WorkflowTemplate {
+  // Required. The template id.
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). Cannot begin or end with underscore
+  // or hyphen. Must consist of between 3 and 50 characters.
+  string id = 2;
+
+  // Output only. The "resource name" of the template, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}/workflowTemplates/{template_id}`
+  string name = 1;
+
+  // Optional. Used to perform a consistent read-modify-write.
+  //
+  // This field should be left blank for a `CreateWorkflowTemplate` request. It
+  // is required for an `UpdateWorkflowTemplate` request, and must match the
+  // current server version. A typical update template flow would fetch the
+  // current template with a `GetWorkflowTemplate` request, which will return
+  // the current template with the `version` field filled in with the
+  // current server version. The user updates other fields in the template,
+  // then returns it as part of the `UpdateWorkflowTemplate` request.
+  int32 version = 3;
+
+  // Output only. The time template was created.
+  google.protobuf.Timestamp create_time = 4;
+
+  // Output only. The time template was last updated.
+  google.protobuf.Timestamp update_time = 5;
+
+  // Optional. The labels to associate with this template. These labels
+  // will be propagated to all jobs and clusters created by the workflow
+  // instance.
+  //
+  // Label **keys** must contain 1 to 63 characters, and must conform to
+  // [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  //
+  // Label **values** may be empty, but, if present, must contain 1 to 63
+  // characters, and must conform to
+  // [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  //
+  // No more than 32 labels can be associated with a template.
+  map<string, string> labels = 6;
+
+  // Required. WorkflowTemplate scheduling information.
+  WorkflowTemplatePlacement placement = 7;
+
+  // Required. The Directed Acyclic Graph of Jobs to submit.
+  repeated OrderedJob jobs = 8;
+
+  // Optional. Template parameters whose values are substituted into the
+  // template. Values for parameters must be provided when the template is
+  // instantiated.
+  repeated TemplateParameter parameters = 9;
+}
+
+// Specifies workflow execution target.
+//
+// Either `managed_cluster` or `cluster_selector` is required.
+message WorkflowTemplatePlacement {
+  // Required. Specifies where workflow executes; either on a managed
+  // cluster or an existing cluster chosen by labels.
+  oneof placement {
+    // Optional. A cluster that is managed by the workflow.
+    ManagedCluster managed_cluster = 1;
+
+    // Optional. A selector that chooses target cluster for jobs based
+    // on metadata.
+    //
+    // The selector is evaluated at the time each job is submitted.
+    ClusterSelector cluster_selector = 2;
+  }
+}
+
+// Cluster that is managed by the workflow.
+message ManagedCluster {
+  // Required. The cluster name prefix. A unique cluster name will be formed by
+  // appending a random suffix.
+  //
+  // The name must contain only lower-case letters (a-z), numbers (0-9),
+  // and hyphens (-). Must begin with a letter. Cannot begin or end with
+  // hyphen. Must consist of between 2 and 35 characters.
+  string cluster_name = 2;
+
+  // Required. The cluster configuration.
+  ClusterConfig config = 3;
+
+  // Optional. The labels to associate with this cluster.
+  //
+  // Label keys must be between 1 and 63 characters long, and must conform to
+  // the following PCRE regular expression:
+  // [\p{Ll}\p{Lo}][\p{Ll}\p{Lo}\p{N}_-]{0,62}
+  //
+  // Label values must be between 1 and 63 characters long, and must conform to
+  // the following PCRE regular expression: [\p{Ll}\p{Lo}\p{N}_-]{0,63}
+  //
+  // No more than 32 labels can be associated with a given cluster.
+  map<string, string> labels = 4;
+}
+
+// A selector that chooses target cluster for jobs based on metadata.
+message ClusterSelector {
+  // Optional. The zone where workflow process executes. This parameter does not
+  // affect the selection of the cluster.
+  //
+  // If unspecified, the zone of the first cluster matching the selector
+  // is used.
+  string zone = 1;
+
+  // Required. The cluster labels. Cluster must have all labels
+  // to match.
+  map<string, string> cluster_labels = 2;
+}
+
+// A job executed by the workflow.
+message OrderedJob {
+  // Required. The step id. The id must be unique among all jobs
+  // within the template.
+  //
+  // The step id is used as prefix for job id, as job
+  // `goog-dataproc-workflow-step-id` label, and in
+  // [prerequisiteStepIds][google.cloud.dataproc.v1beta2.OrderedJob.prerequisite_step_ids] field from other
+  // steps.
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). Cannot begin or end with underscore
+  // or hyphen. Must consist of between 3 and 50 characters.
+  string step_id = 1;
+
+  // Required. The job definition.
+  oneof job_type {
+    // Job is a Hadoop job.
+    HadoopJob hadoop_job = 2;
+
+    // Job is a Spark job.
+    SparkJob spark_job = 3;
+
+    // Job is a Pyspark job.
+    PySparkJob pyspark_job = 4;
+
+    // Job is a Hive job.
+    HiveJob hive_job = 5;
+
+    // Job is a Pig job.
+    PigJob pig_job = 6;
+
+    // Job is a SparkSql job.
+    SparkSqlJob spark_sql_job = 7;
+  }
+
+  // Optional. The labels to associate with this job.
+  //
+  // Label keys must be between 1 and 63 characters long, and must conform to
+  // the following regular expression:
+  // [\p{Ll}\p{Lo}][\p{Ll}\p{Lo}\p{N}_-]{0,62}
+  //
+  // Label values must be between 1 and 63 characters long, and must conform to
+  // the following regular expression: [\p{Ll}\p{Lo}\p{N}_-]{0,63}
+  //
+  // No more than 32 labels can be associated with a given job.
+  map<string, string> labels = 8;
+
+  // Optional. Job scheduling configuration.
+  JobScheduling scheduling = 9;
+
+  // Optional. The optional list of prerequisite job step_ids.
+  // If not specified, the job will start at the beginning of workflow.
+  repeated string prerequisite_step_ids = 10;
+}
+
+// A configurable parameter that replaces one or more fields in the template.
+// Parameterizable fields:
+// - Labels
+// - File uris
+// - Job properties
+// - Job arguments
+// - Script variables
+// - Main class (in HadoopJob and SparkJob)
+// - Zone (in ClusterSelector)
+message TemplateParameter {
+  // Required.  Parameter name.
+  // The parameter name is used as the key, and paired with the
+  // parameter value, which are passed to the template when the template
+  // is instantiated.
+  // The name must contain only capital letters (A-Z), numbers (0-9), and
+  // underscores (_), and must not start with a number. The maximum length is
+  // 40 characters.
+  string name = 1;
+
+  // Required. Paths to all fields that the parameter replaces.
+  // A field is allowed to appear in at most one parameter's list of field paths.
+  //
+  // A field path is similar in syntax to a [google.protobuf.FieldMask][google.protobuf.FieldMask].
+  // For example, a field path that references the zone field of a workflow
+  // template's cluster selector would be specified as
+  // `placement.clusterSelector.zone`.
+  //
+  // Also, field paths can reference fields using the following syntax:
+  //
+  // * Values in maps can be referenced by key:
+  //     * labels['key']
+  //     * placement.clusterSelector.clusterLabels['key']
+  //     * placement.managedCluster.labels['key']
+  //     * placement.clusterSelector.clusterLabels['key']
+  //     * jobs['step-id'].labels['key']
+  //
+  // * Jobs in the jobs list can be referenced by step-id:
+  //     * jobs['step-id'].hadoopJob.mainJarFileUri
+  //     * jobs['step-id'].hiveJob.queryFileUri
+  //     * jobs['step-id'].pySparkJob.mainPythonFileUri
+  //     * jobs['step-id'].hadoopJob.jarFileUris[0]
+  //     * jobs['step-id'].hadoopJob.archiveUris[0]
+  //     * jobs['step-id'].hadoopJob.fileUris[0]
+  //     * jobs['step-id'].pySparkJob.pythonFileUris[0]
+  //
+  // * Items in repeated fields can be referenced by a zero-based index:
+  //     * jobs['step-id'].sparkJob.args[0]
+  //
+  // * Other examples:
+  //     * jobs['step-id'].hadoopJob.properties['key']
+  //     * jobs['step-id'].hadoopJob.args[0]
+  //     * jobs['step-id'].hiveJob.scriptVariables['key']
+  //     * jobs['step-id'].hadoopJob.mainJarFileUri
+  //     * placement.clusterSelector.zone
+  //
+  // It may not be possible to parameterize maps and repeated fields in their
+  // entirety since only individual map values and individual items in repeated
+  // fields can be referenced. For example, the following field paths are
+  // invalid:
+  //
+  // - placement.clusterSelector.clusterLabels
+  // - jobs['step-id'].sparkJob.args
+  repeated string fields = 2;
+
+  // Optional. Brief description of the parameter.
+  // Must not exceed 1024 characters.
+  string description = 3;
+
+  // Optional. Validation rules to be applied to this parameter's value.
+  ParameterValidation validation = 4;
+}
+
+// Configuration for parameter validation.
+message ParameterValidation {
+  // Required. The type of validation to be performed.
+  oneof validation_type {
+    // Validation based on regular expressions.
+    RegexValidation regex = 1;
+
+    // Validation based on a list of allowed values.
+    ValueValidation values = 2;
+  }
+}
+
+// Validation based on regular expressions.
+message RegexValidation {
+  // Required. RE2 regular expressions used to validate the parameter's value.
+  // The value must match the regex in its entirety (substring
+  // matches are not sufficient).
+  repeated string regexes = 1;
+}
+
+// Validation based on a list of allowed values.
+message ValueValidation {
+  // Required. List of allowed values for the parameter.
+  repeated string values = 1;
+}
+
+// A Cloud Dataproc workflow template resource.
+message WorkflowMetadata {
+  // The operation state.
+  enum State {
+    // Unused.
+    UNKNOWN = 0;
+
+    // The operation has been created.
+    PENDING = 1;
+
+    // The operation is running.
+    RUNNING = 2;
+
+    // The operation is done; either cancelled or completed.
+    DONE = 3;
+  }
+
+  // Output only. The "resource name" of the template.
+  string template = 1;
+
+  // Output only. The version of template at the time of
+  // workflow instantiation.
+  int32 version = 2;
+
+  // Output only. The create cluster operation metadata.
+  ClusterOperation create_cluster = 3;
+
+  // Output only. The workflow graph.
+  WorkflowGraph graph = 4;
+
+  // Output only. The delete cluster operation metadata.
+  ClusterOperation delete_cluster = 5;
+
+  // Output only. The workflow state.
+  State state = 6;
+
+  // Output only. The name of the target cluster.
+  string cluster_name = 7;
+
+  // Map from parameter names to values that were used for those parameters.
+  map<string, string> parameters = 8;
+
+  // Output only. Workflow start time.
+  google.protobuf.Timestamp start_time = 9;
+
+  // Output only. Workflow end time.
+  google.protobuf.Timestamp end_time = 10;
+
+  // Output only. The UUID of target cluster.
+  string cluster_uuid = 11;
+}
+
+// The cluster operation triggered by a workflow.
+message ClusterOperation {
+  // Output only. The id of the cluster operation.
+  string operation_id = 1;
+
+  // Output only. Error, if operation failed.
+  string error = 2;
+
+  // Output only. Indicates the operation is done.
+  bool done = 3;
+}
+
+// The workflow graph.
+message WorkflowGraph {
+  // Output only. The workflow nodes.
+  repeated WorkflowNode nodes = 1;
+}
+
+// The workflow node.
+message WorkflowNode {
+  // The workflow node state.
+  enum NodeState {
+    // State is unspecified.
+    NODE_STATUS_UNSPECIFIED = 0;
+
+    // The node is awaiting prerequisite node to finish.
+    BLOCKED = 1;
+
+    // The node is runnable but not running.
+    RUNNABLE = 2;
+
+    // The node is running.
+    RUNNING = 3;
+
+    // The node completed successfully.
+    COMPLETED = 4;
+
+    // The node failed. A node can be marked FAILED because
+    // its ancestor or peer failed.
+    FAILED = 5;
+  }
+
+  // Output only. The name of the node.
+  string step_id = 1;
+
+  // Output only. Node's prerequisite nodes.
+  repeated string prerequisite_step_ids = 2;
+
+  // Output only. The job id; populated after the node enters RUNNING state.
+  string job_id = 3;
+
+  // Output only. The node state.
+  NodeState state = 5;
+
+  // Output only. The error detail.
+  string error = 6;
+}
+
+// A request to create a workflow template.
+message CreateWorkflowTemplateRequest {
+  // Required. The "resource name" of the region, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}`
+  string parent = 1;
+
+  // Required. The Dataproc workflow template to create.
+  WorkflowTemplate template = 2;
+}
+
+// A request to fetch a workflow template.
+message GetWorkflowTemplateRequest {
+  // Required. The "resource name" of the workflow template, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}/workflowTemplates/{template_id}`
+  string name = 1;
+
+  // Optional. The version of workflow template to retrieve. Only previously
+  // instatiated versions can be retrieved.
+  //
+  // If unspecified, retrieves the current version.
+  int32 version = 2;
+}
+
+// A request to instantiate a workflow template.
+message InstantiateWorkflowTemplateRequest {
+  // Required. The "resource name" of the workflow template, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}/workflowTemplates/{template_id}`
+  string name = 1;
+
+  // Optional. The version of workflow template to instantiate. If specified,
+  // the workflow will be instantiated only if the current version of
+  // the workflow template has the supplied version.
+  //
+  // This option cannot be used to instantiate a previous version of
+  // workflow template.
+  int32 version = 2;
+
+  // Deprecated. Please use `request_id` field instead.
+  string instance_id = 3 [deprecated = true];
+
+  // Optional. A tag that prevents multiple concurrent workflow
+  // instances with the same tag from running. This mitigates risk of
+  // concurrent instances started due to retries.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The tag must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 5;
+
+  // Optional. Map from parameter names to values that should be used for those
+  // parameters. Values may not exceed 100 characters.
+  map<string, string> parameters = 4;
+}
+
+// A request to instantiate an inline workflow template.
+message InstantiateInlineWorkflowTemplateRequest {
+  // Required. The "resource name" of the workflow template region, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}`
+  string parent = 1;
+
+  // Required. The workflow template to instantiate.
+  WorkflowTemplate template = 2;
+
+  // Deprecated. Please use `request_id` field instead.
+  string instance_id = 3;
+
+  // Optional. A tag that prevents multiple concurrent workflow
+  // instances with the same tag from running. This mitigates risk of
+  // concurrent instances started due to retries.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The tag must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 4;
+}
+
+// A request to update a workflow template.
+message UpdateWorkflowTemplateRequest {
+  // Required. The updated workflow template.
+  //
+  // The `template.version` field must match the current version.
+  WorkflowTemplate template = 1;
+}
+
+// A request to list workflow templates in a project.
+message ListWorkflowTemplatesRequest {
+  // Required. The "resource name" of the region, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}`
+  string parent = 1;
+
+  // Optional. The maximum number of results to return in each response.
+  int32 page_size = 2;
+
+  // Optional. The page token, returned by a previous call, to request the
+  // next page of results.
+  string page_token = 3;
+}
+
+// A response to a request to list workflow templates in a project.
+message ListWorkflowTemplatesResponse {
+  // Output only. WorkflowTemplates list.
+  repeated WorkflowTemplate templates = 1;
+
+  // Output only. This token is included in the response if there are more results
+  // to fetch. To fetch additional results, provide this value as the
+  // page_token in a subsequent <code>ListWorkflowTemplatesRequest</code>.
+  string next_page_token = 2;
+}
+
+// A request to delete a workflow template.
+//
+// Currently started workflows will remain running.
+message DeleteWorkflowTemplateRequest {
+  // Required. The "resource name" of the workflow template, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}/workflowTemplates/{template_id}`
+  string name = 1;
+
+  // Optional. The version of workflow template to delete. If specified,
+  // will only delete the template if the current server version matches
+  // specified version.
+  int32 version = 2;
+}
diff --git a/dataproc/google/cloud/dataproc_v1beta2/proto/clusters.proto b/dataproc/google/cloud/dataproc_v1beta2/proto/clusters.proto
new file mode 100644
index 000000000000..fd3c86a0ffb8
--- /dev/null
+++ b/dataproc/google/cloud/dataproc_v1beta2/proto/clusters.proto
@@ -0,0 +1,731 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.dataproc.v1beta2;
+
+import "google/api/annotations.proto";
+import "google/cloud/dataproc/v1beta2/shared.proto";
+import "google/cloud/dataproc/v1beta2/operations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2;dataproc";
+option java_multiple_files = true;
+option java_outer_classname = "ClustersProto";
+option java_package = "com.google.cloud.dataproc.v1beta2";
+
+
+// The ClusterControllerService provides methods to manage clusters
+// of Compute Engine instances.
+service ClusterController {
+  // Creates a cluster in a project.
+  rpc CreateCluster(CreateClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta2/projects/{project_id}/regions/{region}/clusters"
+      body: "cluster"
+    };
+  }
+
+  // Updates a cluster in a project.
+  rpc UpdateCluster(UpdateClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v1beta2/projects/{project_id}/regions/{region}/clusters/{cluster_name}"
+      body: "cluster"
+    };
+  }
+
+  // Deletes a cluster in a project.
+  rpc DeleteCluster(DeleteClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      delete: "/v1beta2/projects/{project_id}/regions/{region}/clusters/{cluster_name}"
+    };
+  }
+
+  // Gets the resource representation for a cluster in a project.
+  rpc GetCluster(GetClusterRequest) returns (Cluster) {
+    option (google.api.http) = {
+      get: "/v1beta2/projects/{project_id}/regions/{region}/clusters/{cluster_name}"
+    };
+  }
+
+  // Lists all regions/{region}/clusters in a project.
+  rpc ListClusters(ListClustersRequest) returns (ListClustersResponse) {
+    option (google.api.http) = {
+      get: "/v1beta2/projects/{project_id}/regions/{region}/clusters"
+    };
+  }
+
+  // Gets cluster diagnostic information.
+  // After the operation completes, the Operation.response field
+  // contains `DiagnoseClusterOutputLocation`.
+  rpc DiagnoseCluster(DiagnoseClusterRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta2/projects/{project_id}/regions/{region}/clusters/{cluster_name}:diagnose"
+      body: "*"
+    };
+  }
+}
+
+// Describes the identifying information, config, and status of
+// a cluster of Compute Engine instances.
+message Cluster {
+  // Required. The Google Cloud Platform project ID that the cluster belongs to.
+  string project_id = 1;
+
+  // Required. The cluster name. Cluster names within a project must be
+  // unique. Names of deleted clusters can be reused.
+  string cluster_name = 2;
+
+  // Required. The cluster config. Note that Cloud Dataproc may set
+  // default values, and values may change when clusters are updated.
+  ClusterConfig config = 3;
+
+  // Optional. The labels to associate with this cluster.
+  // Label **keys** must contain 1 to 63 characters, and must conform to
+  // [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  // Label **values** may be empty, but, if present, must contain 1 to 63
+  // characters, and must conform to [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  // No more than 32 labels can be associated with a cluster.
+  map<string, string> labels = 8;
+
+  // Output only. Cluster status.
+  ClusterStatus status = 4;
+
+  // Output only. The previous cluster status.
+  repeated ClusterStatus status_history = 7;
+
+  // Output only. A cluster UUID (Unique Universal Identifier). Cloud Dataproc
+  // generates this value when it creates the cluster.
+  string cluster_uuid = 6;
+
+  // Output only. Contains cluster daemon metrics such as HDFS and YARN stats.
+  //
+  // **Beta Feature**: This report is available for testing purposes only. It may
+  // be changed before final release.
+  ClusterMetrics metrics = 9;
+}
+
+// The cluster config.
+message ClusterConfig {
+  // Optional. A Cloud Storage staging bucket used for sharing generated
+  // SSH keys and config. If you do not specify a staging bucket, Cloud
+  // Dataproc will determine an appropriate Cloud Storage location (US,
+  // ASIA, or EU) for your cluster's staging bucket according to the Google
+  // Compute Engine zone where your cluster is deployed, and then it will create
+  // and manage this project-level, per-location bucket for you.
+  string config_bucket = 1;
+
+  // Required. The shared Compute Engine config settings for
+  // all instances in a cluster.
+  GceClusterConfig gce_cluster_config = 8;
+
+  // Optional. The Compute Engine config settings for
+  // the master instance in a cluster.
+  InstanceGroupConfig master_config = 9;
+
+  // Optional. The Compute Engine config settings for
+  // worker instances in a cluster.
+  InstanceGroupConfig worker_config = 10;
+
+  // Optional. The Compute Engine config settings for
+  // additional worker instances in a cluster.
+  InstanceGroupConfig secondary_worker_config = 12;
+
+  // Optional. The config settings for software inside the cluster.
+  SoftwareConfig software_config = 13;
+
+  // Optional. The config setting for auto delete cluster schedule.
+  LifecycleConfig lifecycle_config = 14;
+
+  // Optional. Commands to execute on each node after config is
+  // completed. By default, executables are run on master and all worker nodes.
+  // You can test a node's <code>role</code> metadata to run an executable on
+  // a master or worker node, as shown below using `curl` (you can also use `wget`):
+  //
+  //     ROLE=$(curl -H Metadata-Flavor:Google http://metadata/computeMetadata/v1beta2/instance/attributes/dataproc-role)
+  //     if [[ "${ROLE}" == 'Master' ]]; then
+  //       ... master specific actions ...
+  //     else
+  //       ... worker specific actions ...
+  //     fi
+  repeated NodeInitializationAction initialization_actions = 11;
+
+  // Optional. Encryption settings for the cluster.
+  EncryptionConfig encryption_config = 15;
+}
+
+// Encryption settings for the cluster.
+message EncryptionConfig {
+  // Optional. The Cloud KMS key name to use for PD disk encryption for all
+  // instances in the cluster.
+  string gce_pd_kms_key_name = 1;
+}
+
+// Common config settings for resources of Compute Engine cluster
+// instances, applicable to all instances in the cluster.
+message GceClusterConfig {
+  // Optional. The zone where the Compute Engine cluster will be located.
+  // On a create request, it is required in the "global" region. If omitted
+  // in a non-global Cloud Dataproc region, the service will pick a zone in the
+  // corresponding Compute Engine region. On a get request, zone will always be
+  // present.
+  //
+  // A full URL, partial URI, or short name are valid. Examples:
+  //
+  // * `https://www.googleapis.com/compute/v1/projects/[project_id]/zones/[zone]`
+  // * `projects/[project_id]/zones/[zone]`
+  // * `us-central1-f`
+  string zone_uri = 1;
+
+  // Optional. The Compute Engine network to be used for machine
+  // communications. Cannot be specified with subnetwork_uri. If neither
+  // `network_uri` nor `subnetwork_uri` is specified, the "default" network of
+  // the project is used, if it exists. Cannot be a "Custom Subnet Network" (see
+  // [Using Subnetworks](/compute/docs/subnetworks) for more information).
+  //
+  // A full URL, partial URI, or short name are valid. Examples:
+  //
+  // * `https://www.googleapis.com/compute/v1/projects/[project_id]/regions/global/default`
+  // * `projects/[project_id]/regions/global/default`
+  // * `default`
+  string network_uri = 2;
+
+  // Optional. The Compute Engine subnetwork to be used for machine
+  // communications. Cannot be specified with network_uri.
+  //
+  // A full URL, partial URI, or short name are valid. Examples:
+  //
+  // * `https://www.googleapis.com/compute/v1/projects/[project_id]/regions/us-east1/sub0`
+  // * `projects/[project_id]/regions/us-east1/sub0`
+  // * `sub0`
+  string subnetwork_uri = 6;
+
+  // Optional. If true, all instances in the cluster will only have internal IP
+  // addresses. By default, clusters are not restricted to internal IP addresses,
+  // and will have ephemeral external IP addresses assigned to each instance.
+  // This `internal_ip_only` restriction can only be enabled for subnetwork
+  // enabled networks, and all off-cluster dependencies must be configured to be
+  // accessible without external IP addresses.
+  bool internal_ip_only = 7;
+
+  // Optional. The service account of the instances. Defaults to the default
+  // Compute Engine service account. Custom service accounts need
+  // permissions equivalent to the following IAM roles:
+  //
+  // * roles/logging.logWriter
+  // * roles/storage.objectAdmin
+  //
+  // (see https://cloud.google.com/compute/docs/access/service-accounts#custom_service_accounts
+  // for more information).
+  // Example: `[account_id]@[project_id].iam.gserviceaccount.com`
+  string service_account = 8;
+
+  // Optional. The URIs of service account scopes to be included in
+  // Compute Engine instances. The following base set of scopes is always
+  // included:
+  //
+  // * https://www.googleapis.com/auth/cloud.useraccounts.readonly
+  // * https://www.googleapis.com/auth/devstorage.read_write
+  // * https://www.googleapis.com/auth/logging.write
+  //
+  // If no scopes are specified, the following defaults are also provided:
+  //
+  // * https://www.googleapis.com/auth/bigquery
+  // * https://www.googleapis.com/auth/bigtable.admin.table
+  // * https://www.googleapis.com/auth/bigtable.data
+  // * https://www.googleapis.com/auth/devstorage.full_control
+  repeated string service_account_scopes = 3;
+
+  // The Compute Engine tags to add to all instances (see
+  // [Tagging instances](/compute/docs/label-or-tag-resources#tags)).
+  repeated string tags = 4;
+
+  // The Compute Engine metadata entries to add to all instances (see
+  // [Project and instance metadata](https://cloud.google.com/compute/docs/storing-retrieving-metadata#project_and_instance_metadata)).
+  map<string, string> metadata = 5;
+}
+
+// Optional. The config settings for Compute Engine resources in
+// an instance group, such as a master or worker group.
+message InstanceGroupConfig {
+  // Optional. The number of VM instances in the instance group.
+  // For master instance groups, must be set to 1.
+  int32 num_instances = 1;
+
+  // Output only. The list of instance names. Cloud Dataproc derives the names
+  // from `cluster_name`, `num_instances`, and the instance group.
+  repeated string instance_names = 2;
+
+  // Optional. The Compute Engine image resource used for cluster
+  // instances. It can be specified or may be inferred from
+  // `SoftwareConfig.image_version`.
+  string image_uri = 3;
+
+  // Optional. The Compute Engine machine type used for cluster instances.
+  //
+  // A full URL, partial URI, or short name are valid. Examples:
+  //
+  // * `https://www.googleapis.com/compute/v1/projects/[project_id]/zones/us-east1-a/machineTypes/n1-standard-2`
+  // * `projects/[project_id]/zones/us-east1-a/machineTypes/n1-standard-2`
+  // * `n1-standard-2`
+  //
+  // **Auto Zone Exception**: If you are using the Cloud Dataproc
+  // [Auto Zone Placement](/dataproc/docs/concepts/configuring-clusters/auto-zone#using_auto_zone_placement)
+  // feature, you must use the short name of the machine type
+  // resource, for example, `n1-standard-2`.
+  string machine_type_uri = 4;
+
+  // Optional. Disk option config settings.
+  DiskConfig disk_config = 5;
+
+  // Optional. Specifies that this instance group contains preemptible instances.
+  bool is_preemptible = 6;
+
+  // Output only. The config for Compute Engine Instance Group
+  // Manager that manages this group.
+  // This is only used for preemptible instance groups.
+  ManagedGroupConfig managed_group_config = 7;
+
+  // Optional. The Compute Engine accelerator configuration for these
+  // instances.
+  //
+  // **Beta Feature**: This feature is still under development. It may be
+  // changed before final release.
+  repeated AcceleratorConfig accelerators = 8;
+
+  // Optional. Specifies the minimum cpu platform for the Instance Group.
+  // See [Cloud Dataproc&rarr;Minimum CPU Platform]
+  // (/dataproc/docs/concepts/compute/dataproc-min-cpu).
+  string min_cpu_platform = 9;
+}
+
+// Specifies the resources used to actively manage an instance group.
+message ManagedGroupConfig {
+  // Output only. The name of the Instance Template used for the Managed
+  // Instance Group.
+  string instance_template_name = 1;
+
+  // Output only. The name of the Instance Group Manager for this group.
+  string instance_group_manager_name = 2;
+}
+
+// Specifies the type and number of accelerator cards attached to the instances
+// of an instance group (see [GPUs on Compute Engine](/compute/docs/gpus/)).
+message AcceleratorConfig {
+  // Full URL, partial URI, or short name of the accelerator type resource to
+  // expose to this instance. See [Compute Engine AcceleratorTypes](
+  // /compute/docs/reference/beta/acceleratorTypes)
+  //
+  // Examples
+  // * `https://www.googleapis.com/compute/beta/projects/[project_id]/zones/us-east1-a/acceleratorTypes/nvidia-tesla-k80`
+  // * `projects/[project_id]/zones/us-east1-a/acceleratorTypes/nvidia-tesla-k80`
+  // * `nvidia-tesla-k80`
+  //
+  // **Auto Zone Exception**: If you are using the Cloud Dataproc
+  // [Auto Zone Placement](/dataproc/docs/concepts/configuring-clusters/auto-zone#using_auto_zone_placement)
+  // feature, you must use the short name of the accelerator type
+  // resource, for example, `nvidia-tesla-k80`.
+  string accelerator_type_uri = 1;
+
+  // The number of the accelerator cards of this type exposed to this instance.
+  int32 accelerator_count = 2;
+}
+
+// Specifies the config of disk options for a group of VM instances.
+message DiskConfig {
+  // Optional. Type of the boot disk (default is "pd-standard").
+  // Valid values: "pd-ssd" (Persistent Disk Solid State Drive) or
+  // "pd-standard" (Persistent Disk Hard Disk Drive).
+  string boot_disk_type = 3;
+
+  // Optional. Size in GB of the boot disk (default is 500GB).
+  int32 boot_disk_size_gb = 1;
+
+  // Optional. Number of attached SSDs, from 0 to 4 (default is 0).
+  // If SSDs are not attached, the boot disk is used to store runtime logs and
+  // [HDFS](https://hadoop.apache.org/docs/r1.2.1/hdfs_user_guide.html) data.
+  // If one or more SSDs are attached, this runtime bulk
+  // data is spread across them, and the boot disk contains only basic
+  // config and installed binaries.
+  int32 num_local_ssds = 2;
+}
+
+// Specifies the cluster auto-delete schedule configuration.
+message LifecycleConfig {
+  // Optional. The duration to keep the cluster alive while idling.
+  // Passing this threshold will cause the cluster to be
+  // deleted. Valid range: **[10m, 14d]**.
+  //
+  // Example: **"10m"**, the minimum value, to delete the
+  // cluster when it has had no jobs running for 10 minutes.
+  google.protobuf.Duration idle_delete_ttl = 1;
+
+  // Optional. Either the exact time the cluster should be deleted at or
+  // the cluster maximum age.
+  oneof ttl {
+    // Optional. The time when cluster will be auto-deleted.
+    google.protobuf.Timestamp auto_delete_time = 2;
+
+    // Optional. The lifetime duration of cluster. The cluster will be
+    // auto-deleted at the end of this period. Valid range: **[10m, 14d]**.
+    //
+    // Example: **"1d"**, to delete the cluster 1 day after its creation..
+    google.protobuf.Duration auto_delete_ttl = 3;
+  }
+}
+
+// Specifies an executable to run on a fully configured node and a
+// timeout period for executable completion.
+message NodeInitializationAction {
+  // Required. Cloud Storage URI of executable file.
+  string executable_file = 1;
+
+  // Optional. Amount of time executable has to complete. Default is
+  // 10 minutes. Cluster creation fails with an explanatory error message (the
+  // name of the executable that caused the error and the exceeded timeout
+  // period) if the executable is not completed at end of the timeout period.
+  google.protobuf.Duration execution_timeout = 2;
+}
+
+// The status of a cluster and its instances.
+message ClusterStatus {
+  // The cluster state.
+  enum State {
+    // The cluster state is unknown.
+    UNKNOWN = 0;
+
+    // The cluster is being created and set up. It is not ready for use.
+    CREATING = 1;
+
+    // The cluster is currently running and healthy. It is ready for use.
+    RUNNING = 2;
+
+    // The cluster encountered an error. It is not ready for use.
+    ERROR = 3;
+
+    // The cluster is being deleted. It cannot be used.
+    DELETING = 4;
+
+    // The cluster is being updated. It continues to accept and process jobs.
+    UPDATING = 5;
+  }
+
+  // The cluster substate.
+  enum Substate {
+    // The cluster substate is unknown.
+    UNSPECIFIED = 0;
+
+    // The cluster is known to be in an unhealthy state
+    // (for example, critical daemons are not running or HDFS capacity is
+    // exhausted).
+    //
+    // Applies to RUNNING state.
+    UNHEALTHY = 1;
+
+    // The agent-reported status is out of date (may occur if
+    // Cloud Dataproc loses communication with Agent).
+    //
+    // Applies to RUNNING state.
+    STALE_STATUS = 2;
+  }
+
+  // Output only. The cluster's state.
+  State state = 1;
+
+  // Output only. Optional details of cluster's state.
+  string detail = 2;
+
+  // Output only. Time when this state was entered.
+  google.protobuf.Timestamp state_start_time = 3;
+
+  // Output only. Additional state information that includes
+  // status reported by the agent.
+  Substate substate = 4;
+}
+
+// Specifies the selection and config of software inside the cluster.
+message SoftwareConfig {
+  // Optional. The version of software inside the cluster. It must be one of the supported
+  // [Cloud Dataproc Versions](/dataproc/docs/concepts/versioning/dataproc-versions#supported_cloud_dataproc_versions),
+  // such as "1.2" (including a subminor version, such as "1.2.29"), or the
+  // ["preview" version](/dataproc/docs/concepts/versioning/dataproc-versions#other_versions).
+  // If unspecified, it defaults to the latest version.
+  string image_version = 1;
+
+  // Optional. The properties to set on daemon config files.
+  //
+  // Property keys are specified in `prefix:property` format, such as
+  // `core:fs.defaultFS`. The following are supported prefixes
+  // and their mappings:
+  //
+  // * capacity-scheduler: `capacity-scheduler.xml`
+  // * core:   `core-site.xml`
+  // * distcp: `distcp-default.xml`
+  // * hdfs:   `hdfs-site.xml`
+  // * hive:   `hive-site.xml`
+  // * mapred: `mapred-site.xml`
+  // * pig:    `pig.properties`
+  // * spark:  `spark-defaults.conf`
+  // * yarn:   `yarn-site.xml`
+  //
+  // For more information, see
+  // [Cluster properties](/dataproc/docs/concepts/cluster-properties).
+  map<string, string> properties = 2;
+}
+
+// Contains cluster daemon metrics, such as HDFS and YARN stats.
+//
+// **Beta Feature**: This report is available for testing purposes only. It may
+// be changed before final release.
+message ClusterMetrics {
+  // The HDFS metrics.
+  map<string, int64> hdfs_metrics = 1;
+
+  // The YARN metrics.
+  map<string, int64> yarn_metrics = 2;
+}
+
+// A request to create a cluster.
+message CreateClusterRequest {
+  // Required. The ID of the Google Cloud Platform project that the cluster
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The cluster to create.
+  Cluster cluster = 2;
+
+  // Optional. A unique id used to identify the request. If the server
+  // receives two [CreateClusterRequest][google.cloud.dataproc.v1beta2.CreateClusterRequest] requests  with the same
+  // id, then the second request will be ignored and the
+  // first [google.longrunning.Operation][google.longrunning.Operation] created and stored in the backend
+  // is returned.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 4;
+}
+
+// A request to update a cluster.
+message UpdateClusterRequest {
+  // Required. The ID of the Google Cloud Platform project the
+  // cluster belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 5;
+
+  // Required. The cluster name.
+  string cluster_name = 2;
+
+  // Required. The changes to the cluster.
+  Cluster cluster = 3;
+
+  // Optional. Timeout for graceful YARN decomissioning. Graceful
+  // decommissioning allows removing nodes from the cluster without
+  // interrupting jobs in progress. Timeout specifies how long to wait for jobs
+  // in progress to finish before forcefully removing nodes (and potentially
+  // interrupting jobs). Default timeout is 0 (for forceful decommission), and
+  // the maximum allowed timeout is 1 day.
+  //
+  // Only supported on Dataproc image versions 1.2 and higher.
+  google.protobuf.Duration graceful_decommission_timeout = 6;
+
+  // Required. Specifies the path, relative to `Cluster`, of
+  // the field to update. For example, to change the number of workers
+  // in a cluster to 5, the `update_mask` parameter would be
+  // specified as `config.worker_config.num_instances`,
+  // and the `PATCH` request body would specify the new value, as follows:
+  //
+  //     {
+  //       "config":{
+  //         "workerConfig":{
+  //           "numInstances":"5"
+  //         }
+  //       }
+  //     }
+  //
+  // Similarly, to change the number of preemptible workers in a cluster to 5, the
+  // `update_mask` parameter would be `config.secondary_worker_config.num_instances`,
+  // and the `PATCH` request body would be set as follows:
+  //
+  //     {
+  //       "config":{
+  //         "secondaryWorkerConfig":{
+  //           "numInstances":"5"
+  //         }
+  //       }
+  //     }
+  // <strong>Note:</strong> currently only the following fields can be updated:
+  //
+  // <table>
+  // <tr>
+  // <td><strong>Mask</strong></td><td><strong>Purpose</strong></td>
+  // </tr>
+  // <tr>
+  // <td>labels</td><td>Updates labels</td>
+  // </tr>
+  // <tr>
+  // <td>config.worker_config.num_instances</td><td>Resize primary worker group</td>
+  // </tr>
+  // <tr>
+  // <td>config.secondary_worker_config.num_instances</td><td>Resize secondary worker group</td>
+  // </tr>
+  // <tr>
+  // <td>config.lifecycle_config.auto_delete_ttl</td><td>Reset MAX TTL duration</td>
+  // </tr>
+  // <tr>
+  // <td>config.lifecycle_config.auto_delete_time</td><td>Update MAX TTL deletion timestamp</td>
+  // </tr>
+  // <tr>
+  // <td>config.lifecycle_config.idle_delete_ttl</td><td>Update Idle TTL duration</td>
+  // </tr>
+  // </table>
+  google.protobuf.FieldMask update_mask = 4;
+
+  // Optional. A unique id used to identify the request. If the server
+  // receives two [UpdateClusterRequest][google.cloud.dataproc.v1beta2.UpdateClusterRequest] requests  with the same
+  // id, then the second request will be ignored and the
+  // first [google.longrunning.Operation][google.longrunning.Operation] created and stored in the
+  // backend is returned.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 7;
+}
+
+// A request to delete a cluster.
+message DeleteClusterRequest {
+  // Required. The ID of the Google Cloud Platform project that the cluster
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The cluster name.
+  string cluster_name = 2;
+
+  // Optional. Specifying the `cluster_uuid` means the RPC should fail
+  // (with error NOT_FOUND) if cluster with specified UUID does not exist.
+  string cluster_uuid = 4;
+
+  // Optional. A unique id used to identify the request. If the server
+  // receives two [DeleteClusterRequest][google.cloud.dataproc.v1beta2.DeleteClusterRequest] requests  with the same
+  // id, then the second request will be ignored and the
+  // first [google.longrunning.Operation][google.longrunning.Operation] created and stored in the
+  // backend is returned.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 5;
+}
+
+// Request to get the resource representation for a cluster in a project.
+message GetClusterRequest {
+  // Required. The ID of the Google Cloud Platform project that the cluster
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The cluster name.
+  string cluster_name = 2;
+}
+
+// A request to list the clusters in a project.
+message ListClustersRequest {
+  // Required. The ID of the Google Cloud Platform project that the cluster
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 4;
+
+  // Optional. A filter constraining the clusters to list. Filters are
+  // case-sensitive and have the following syntax:
+  //
+  // field = value [AND [field = value]] ...
+  //
+  // where **field** is one of `status.state`, `clusterName`, or `labels.[KEY]`,
+  // and `[KEY]` is a label key. **value** can be `*` to match all values.
+  // `status.state` can be one of the following: `ACTIVE`, `INACTIVE`,
+  // `CREATING`, `RUNNING`, `ERROR`, `DELETING`, or `UPDATING`. `ACTIVE`
+  // contains the `CREATING`, `UPDATING`, and `RUNNING` states. `INACTIVE`
+  // contains the `DELETING` and `ERROR` states.
+  // `clusterName` is the name of the cluster provided at creation time.
+  // Only the logical `AND` operator is supported; space-separated items are
+  // treated as having an implicit `AND` operator.
+  //
+  // Example filter:
+  //
+  // status.state = ACTIVE AND clusterName = mycluster
+  // AND labels.env = staging AND labels.starred = *
+  string filter = 5;
+
+  // Optional. The standard List page size.
+  int32 page_size = 2;
+
+  // Optional. The standard List page token.
+  string page_token = 3;
+}
+
+// The list of all clusters in a project.
+message ListClustersResponse {
+  // Output only. The clusters in the project.
+  repeated Cluster clusters = 1;
+
+  // Output only. This token is included in the response if there are more
+  // results to fetch. To fetch additional results, provide this value as the
+  // `page_token` in a subsequent <code>ListClustersRequest</code>.
+  string next_page_token = 2;
+}
+
+// A request to collect cluster diagnostic information.
+message DiagnoseClusterRequest {
+  // Required. The ID of the Google Cloud Platform project that the cluster
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The cluster name.
+  string cluster_name = 2;
+}
+
+// The location of diagnostic output.
+message DiagnoseClusterResults {
+  // Output only. The Cloud Storage URI of the diagnostic output.
+  // The output report is a plain text file with a summary of collected
+  // diagnostics.
+  string output_uri = 1;
+}
diff --git a/dataproc/google/cloud/dataproc_v1beta2/proto/jobs.proto b/dataproc/google/cloud/dataproc_v1beta2/proto/jobs.proto
new file mode 100644
index 000000000000..7aff5f462ad1
--- /dev/null
+++ b/dataproc/google/cloud/dataproc_v1beta2/proto/jobs.proto
@@ -0,0 +1,777 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.dataproc.v1beta2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2;dataproc";
+option java_multiple_files = true;
+option java_outer_classname = "JobsProto";
+option java_package = "com.google.cloud.dataproc.v1beta2";
+
+
+// The JobController provides methods to manage jobs.
+service JobController {
+  // Submits a job to a cluster.
+  rpc SubmitJob(SubmitJobRequest) returns (Job) {
+    option (google.api.http) = {
+      post: "/v1beta2/projects/{project_id}/regions/{region}/jobs:submit"
+      body: "*"
+    };
+  }
+
+  // Gets the resource representation for a job in a project.
+  rpc GetJob(GetJobRequest) returns (Job) {
+    option (google.api.http) = {
+      get: "/v1beta2/projects/{project_id}/regions/{region}/jobs/{job_id}"
+    };
+  }
+
+  // Lists regions/{region}/jobs in a project.
+  rpc ListJobs(ListJobsRequest) returns (ListJobsResponse) {
+    option (google.api.http) = {
+      get: "/v1beta2/projects/{project_id}/regions/{region}/jobs"
+    };
+  }
+
+  // Updates a job in a project.
+  rpc UpdateJob(UpdateJobRequest) returns (Job) {
+    option (google.api.http) = {
+      patch: "/v1beta2/projects/{project_id}/regions/{region}/jobs/{job_id}"
+      body: "job"
+    };
+  }
+
+  // Starts a job cancellation request. To access the job resource
+  // after cancellation, call
+  // [regions/{region}/jobs.list](/dataproc/docs/reference/rest/v1beta2/projects.regions.jobs/list) or
+  // [regions/{region}/jobs.get](/dataproc/docs/reference/rest/v1beta2/projects.regions.jobs/get).
+  rpc CancelJob(CancelJobRequest) returns (Job) {
+    option (google.api.http) = {
+      post: "/v1beta2/projects/{project_id}/regions/{region}/jobs/{job_id}:cancel"
+      body: "*"
+    };
+  }
+
+  // Deletes the job from the project. If the job is active, the delete fails,
+  // and the response returns `FAILED_PRECONDITION`.
+  rpc DeleteJob(DeleteJobRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1beta2/projects/{project_id}/regions/{region}/jobs/{job_id}"
+    };
+  }
+}
+
+// The runtime logging config of the job.
+message LoggingConfig {
+  // The Log4j level for job execution. When running an
+  // [Apache Hive](http://hive.apache.org/) job, Cloud
+  // Dataproc configures the Hive client to an equivalent verbosity level.
+  enum Level {
+    // Level is unspecified. Use default level for log4j.
+    LEVEL_UNSPECIFIED = 0;
+
+    // Use ALL level for log4j.
+    ALL = 1;
+
+    // Use TRACE level for log4j.
+    TRACE = 2;
+
+    // Use DEBUG level for log4j.
+    DEBUG = 3;
+
+    // Use INFO level for log4j.
+    INFO = 4;
+
+    // Use WARN level for log4j.
+    WARN = 5;
+
+    // Use ERROR level for log4j.
+    ERROR = 6;
+
+    // Use FATAL level for log4j.
+    FATAL = 7;
+
+    // Turn off log4j.
+    OFF = 8;
+  }
+
+  // The per-package log levels for the driver. This may include
+  // "root" package name to configure rootLogger.
+  // Examples:
+  //   'com.google = FATAL', 'root = INFO', 'org.apache = DEBUG'
+  map<string, Level> driver_log_levels = 2;
+}
+
+// A Cloud Dataproc job for running
+// [Apache Hadoop MapReduce](https://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html)
+// jobs on [Apache Hadoop YARN](https://hadoop.apache.org/docs/r2.7.1/hadoop-yarn/hadoop-yarn-site/YARN.html).
+message HadoopJob {
+  // Required. Indicates the location of the driver's main class. Specify
+  // either the jar file that contains the main class or the main class name.
+  // To specify both, add the jar file to `jar_file_uris`, and then specify
+  // the main class name in this property.
+  oneof driver {
+    // The HCFS URI of the jar file containing the main class.
+    // Examples:
+    //     'gs://foo-bucket/analytics-binaries/extract-useful-metrics-mr.jar'
+    //     'hdfs:/tmp/test-samples/custom-wordcount.jar'
+    //     'file:///home/usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples.jar'
+    string main_jar_file_uri = 1;
+
+    // The name of the driver's main class. The jar file containing the class
+    // must be in the default CLASSPATH or specified in `jar_file_uris`.
+    string main_class = 2;
+  }
+
+  // Optional. The arguments to pass to the driver. Do not
+  // include arguments, such as `-libjars` or `-Dfoo=bar`, that can be set as job
+  // properties, since a collision may occur that causes an incorrect job
+  // submission.
+  repeated string args = 3;
+
+  // Optional. Jar file URIs to add to the CLASSPATHs of the
+  // Hadoop driver and tasks.
+  repeated string jar_file_uris = 4;
+
+  // Optional. HCFS (Hadoop Compatible Filesystem) URIs of files to be copied
+  // to the working directory of Hadoop drivers and distributed tasks. Useful
+  // for naively parallel tasks.
+  repeated string file_uris = 5;
+
+  // Optional. HCFS URIs of archives to be extracted in the working directory of
+  // Hadoop drivers and tasks. Supported file types:
+  // .jar, .tar, .tar.gz, .tgz, or .zip.
+  repeated string archive_uris = 6;
+
+  // Optional. A mapping of property names to values, used to configure Hadoop.
+  // Properties that conflict with values set by the Cloud Dataproc API may be
+  // overwritten. Can include properties set in /etc/hadoop/conf/*-site and
+  // classes in user code.
+  map<string, string> properties = 7;
+
+  // Optional. The runtime log config for job execution.
+  LoggingConfig logging_config = 8;
+}
+
+// A Cloud Dataproc job for running [Apache Spark](http://spark.apache.org/)
+// applications on YARN.
+message SparkJob {
+  // Required. The specification of the main method to call to drive the job.
+  // Specify either the jar file that contains the main class or the main class
+  // name. To pass both a main jar and a main class in that jar, add the jar to
+  // `CommonJob.jar_file_uris`, and then specify the main class name in `main_class`.
+  oneof driver {
+    // The HCFS URI of the jar file that contains the main class.
+    string main_jar_file_uri = 1;
+
+    // The name of the driver's main class. The jar file that contains the class
+    // must be in the default CLASSPATH or specified in `jar_file_uris`.
+    string main_class = 2;
+  }
+
+  // Optional. The arguments to pass to the driver. Do not include arguments,
+  // such as `--conf`, that can be set as job properties, since a collision may
+  // occur that causes an incorrect job submission.
+  repeated string args = 3;
+
+  // Optional. HCFS URIs of jar files to add to the CLASSPATHs of the
+  // Spark driver and tasks.
+  repeated string jar_file_uris = 4;
+
+  // Optional. HCFS URIs of files to be copied to the working directory of
+  // Spark drivers and distributed tasks. Useful for naively parallel tasks.
+  repeated string file_uris = 5;
+
+  // Optional. HCFS URIs of archives to be extracted in the working directory
+  // of Spark drivers and tasks. Supported file types:
+  // .jar, .tar, .tar.gz, .tgz, and .zip.
+  repeated string archive_uris = 6;
+
+  // Optional. A mapping of property names to values, used to configure Spark.
+  // Properties that conflict with values set by the Cloud Dataproc API may be
+  // overwritten. Can include properties set in
+  // /etc/spark/conf/spark-defaults.conf and classes in user code.
+  map<string, string> properties = 7;
+
+  // Optional. The runtime log config for job execution.
+  LoggingConfig logging_config = 8;
+}
+
+// A Cloud Dataproc job for running
+// [Apache PySpark](https://spark.apache.org/docs/0.9.0/python-programming-guide.html)
+// applications on YARN.
+message PySparkJob {
+  // Required. The HCFS URI of the main Python file to use as the driver. Must
+  // be a .py file.
+  string main_python_file_uri = 1;
+
+  // Optional. The arguments to pass to the driver.  Do not include arguments,
+  // such as `--conf`, that can be set as job properties, since a collision may
+  // occur that causes an incorrect job submission.
+  repeated string args = 2;
+
+  // Optional. HCFS file URIs of Python files to pass to the PySpark
+  // framework. Supported file types: .py, .egg, and .zip.
+  repeated string python_file_uris = 3;
+
+  // Optional. HCFS URIs of jar files to add to the CLASSPATHs of the
+  // Python driver and tasks.
+  repeated string jar_file_uris = 4;
+
+  // Optional. HCFS URIs of files to be copied to the working directory of
+  // Python drivers and distributed tasks. Useful for naively parallel tasks.
+  repeated string file_uris = 5;
+
+  // Optional. HCFS URIs of archives to be extracted in the working directory of
+  // .jar, .tar, .tar.gz, .tgz, and .zip.
+  repeated string archive_uris = 6;
+
+  // Optional. A mapping of property names to values, used to configure PySpark.
+  // Properties that conflict with values set by the Cloud Dataproc API may be
+  // overwritten. Can include properties set in
+  // /etc/spark/conf/spark-defaults.conf and classes in user code.
+  map<string, string> properties = 7;
+
+  // Optional. The runtime log config for job execution.
+  LoggingConfig logging_config = 8;
+}
+
+// A list of queries to run on a cluster.
+message QueryList {
+  // Required. The queries to execute. You do not need to terminate a query
+  // with a semicolon. Multiple queries can be specified in one string
+  // by separating each with a semicolon. Here is an example of an Cloud
+  // Dataproc API snippet that uses a QueryList to specify a HiveJob:
+  //
+  //     "hiveJob": {
+  //       "queryList": {
+  //         "queries": [
+  //           "query1",
+  //           "query2",
+  //           "query3;query4",
+  //         ]
+  //       }
+  //     }
+  repeated string queries = 1;
+}
+
+// A Cloud Dataproc job for running [Apache Hive](https://hive.apache.org/)
+// queries on YARN.
+message HiveJob {
+  // Required. The sequence of Hive queries to execute, specified as either
+  // an HCFS file URI or a list of queries.
+  oneof queries {
+    // The HCFS URI of the script that contains Hive queries.
+    string query_file_uri = 1;
+
+    // A list of queries.
+    QueryList query_list = 2;
+  }
+
+  // Optional. Whether to continue executing queries if a query fails.
+  // The default value is `false`. Setting to `true` can be useful when executing
+  // independent parallel queries.
+  bool continue_on_failure = 3;
+
+  // Optional. Mapping of query variable names to values (equivalent to the
+  // Hive command: `SET name="value";`).
+  map<string, string> script_variables = 4;
+
+  // Optional. A mapping of property names and values, used to configure Hive.
+  // Properties that conflict with values set by the Cloud Dataproc API may be
+  // overwritten. Can include properties set in /etc/hadoop/conf/*-site.xml,
+  // /etc/hive/conf/hive-site.xml, and classes in user code.
+  map<string, string> properties = 5;
+
+  // Optional. HCFS URIs of jar files to add to the CLASSPATH of the
+  // Hive server and Hadoop MapReduce (MR) tasks. Can contain Hive SerDes
+  // and UDFs.
+  repeated string jar_file_uris = 6;
+}
+
+// A Cloud Dataproc job for running [Apache Spark SQL](http://spark.apache.org/sql/)
+// queries.
+message SparkSqlJob {
+  // Required. The sequence of Spark SQL queries to execute, specified as
+  // either an HCFS file URI or as a list of queries.
+  oneof queries {
+    // The HCFS URI of the script that contains SQL queries.
+    string query_file_uri = 1;
+
+    // A list of queries.
+    QueryList query_list = 2;
+  }
+
+  // Optional. Mapping of query variable names to values (equivalent to the
+  // Spark SQL command: SET `name="value";`).
+  map<string, string> script_variables = 3;
+
+  // Optional. A mapping of property names to values, used to configure
+  // Spark SQL's SparkConf. Properties that conflict with values set by the
+  // Cloud Dataproc API may be overwritten.
+  map<string, string> properties = 4;
+
+  // Optional. HCFS URIs of jar files to be added to the Spark CLASSPATH.
+  repeated string jar_file_uris = 56;
+
+  // Optional. The runtime log config for job execution.
+  LoggingConfig logging_config = 6;
+}
+
+// A Cloud Dataproc job for running [Apache Pig](https://pig.apache.org/)
+// queries on YARN.
+message PigJob {
+  // Required. The sequence of Pig queries to execute, specified as an HCFS
+  // file URI or a list of queries.
+  oneof queries {
+    // The HCFS URI of the script that contains the Pig queries.
+    string query_file_uri = 1;
+
+    // A list of queries.
+    QueryList query_list = 2;
+  }
+
+  // Optional. Whether to continue executing queries if a query fails.
+  // The default value is `false`. Setting to `true` can be useful when executing
+  // independent parallel queries.
+  bool continue_on_failure = 3;
+
+  // Optional. Mapping of query variable names to values (equivalent to the Pig
+  // command: `name=[value]`).
+  map<string, string> script_variables = 4;
+
+  // Optional. A mapping of property names to values, used to configure Pig.
+  // Properties that conflict with values set by the Cloud Dataproc API may be
+  // overwritten. Can include properties set in /etc/hadoop/conf/*-site.xml,
+  // /etc/pig/conf/pig.properties, and classes in user code.
+  map<string, string> properties = 5;
+
+  // Optional. HCFS URIs of jar files to add to the CLASSPATH of
+  // the Pig Client and Hadoop MapReduce (MR) tasks. Can contain Pig UDFs.
+  repeated string jar_file_uris = 6;
+
+  // Optional. The runtime log config for job execution.
+  LoggingConfig logging_config = 7;
+}
+
+// Cloud Dataproc job config.
+message JobPlacement {
+  // Required. The name of the cluster where the job will be submitted.
+  string cluster_name = 1;
+
+  // Output only. A cluster UUID generated by the Cloud Dataproc service when
+  // the job is submitted.
+  string cluster_uuid = 2;
+}
+
+// Cloud Dataproc job status.
+message JobStatus {
+  // The job state.
+  enum State {
+    // The job state is unknown.
+    STATE_UNSPECIFIED = 0;
+
+    // The job is pending; it has been submitted, but is not yet running.
+    PENDING = 1;
+
+    // Job has been received by the service and completed initial setup;
+    // it will soon be submitted to the cluster.
+    SETUP_DONE = 8;
+
+    // The job is running on the cluster.
+    RUNNING = 2;
+
+    // A CancelJob request has been received, but is pending.
+    CANCEL_PENDING = 3;
+
+    // Transient in-flight resources have been canceled, and the request to
+    // cancel the running job has been issued to the cluster.
+    CANCEL_STARTED = 7;
+
+    // The job cancellation was successful.
+    CANCELLED = 4;
+
+    // The job has completed successfully.
+    DONE = 5;
+
+    // The job has completed, but encountered an error.
+    ERROR = 6;
+
+    // Job attempt has failed. The detail field contains failure details for
+    // this attempt.
+    //
+    // Applies to restartable jobs only.
+    ATTEMPT_FAILURE = 9;
+  }
+
+  // The job substate.
+  enum Substate {
+    // The job substate is unknown.
+    UNSPECIFIED = 0;
+
+    // The Job is submitted to the agent.
+    //
+    // Applies to RUNNING state.
+    SUBMITTED = 1;
+
+    // The Job has been received and is awaiting execution (it may be waiting
+    // for a condition to be met). See the "details" field for the reason for
+    // the delay.
+    //
+    // Applies to RUNNING state.
+    QUEUED = 2;
+
+    // The agent-reported status is out of date, which may be caused by a
+    // loss of communication between the agent and Cloud Dataproc. If the
+    // agent does not send a timely update, the job will fail.
+    //
+    // Applies to RUNNING state.
+    STALE_STATUS = 3;
+  }
+
+  // Output only. A state message specifying the overall job state.
+  State state = 1;
+
+  // Output only. Optional job state details, such as an error
+  // description if the state is <code>ERROR</code>.
+  string details = 2;
+
+  // Output only. The time when this state was entered.
+  google.protobuf.Timestamp state_start_time = 6;
+
+  // Output only. Additional state information, which includes
+  // status reported by the agent.
+  Substate substate = 7;
+}
+
+// Encapsulates the full scoping used to reference a job.
+message JobReference {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Optional. The job ID, which must be unique within the project. The job ID
+  // is generated by the server upon job submission or provided by the user as a
+  // means to perform retries without creating duplicate jobs. The ID must
+  // contain only letters (a-z, A-Z), numbers (0-9), underscores (_), or
+  // hyphens (-). The maximum length is 100 characters.
+  string job_id = 2;
+}
+
+// A YARN application created by a job. Application information is a subset of
+// <code>org.apache.hadoop.yarn.proto.YarnProtos.ApplicationReportProto</code>.
+//
+// **Beta Feature**: This report is available for testing purposes only. It may
+// be changed before final release.
+message YarnApplication {
+  // The application state, corresponding to
+  // <code>YarnProtos.YarnApplicationStateProto</code>.
+  enum State {
+    // Status is unspecified.
+    STATE_UNSPECIFIED = 0;
+
+    // Status is NEW.
+    NEW = 1;
+
+    // Status is NEW_SAVING.
+    NEW_SAVING = 2;
+
+    // Status is SUBMITTED.
+    SUBMITTED = 3;
+
+    // Status is ACCEPTED.
+    ACCEPTED = 4;
+
+    // Status is RUNNING.
+    RUNNING = 5;
+
+    // Status is FINISHED.
+    FINISHED = 6;
+
+    // Status is FAILED.
+    FAILED = 7;
+
+    // Status is KILLED.
+    KILLED = 8;
+  }
+
+  // Required. The application name.
+  string name = 1;
+
+  // Required. The application state.
+  State state = 2;
+
+  // Required. The numerical progress of the application, from 1 to 100.
+  float progress = 3;
+
+  // Optional. The HTTP URL of the ApplicationMaster, HistoryServer, or
+  // TimelineServer that provides application-specific information. The URL uses
+  // the internal hostname, and requires a proxy server for resolution and,
+  // possibly, access.
+  string tracking_url = 4;
+}
+
+// A Cloud Dataproc job resource.
+message Job {
+  // Optional. The fully qualified reference to the job, which can be used to
+  // obtain the equivalent REST path of the job resource. If this property
+  // is not specified when a job is created, the server generates a
+  // <code>job_id</code>.
+  JobReference reference = 1;
+
+  // Required. Job information, including how, when, and where to
+  // run the job.
+  JobPlacement placement = 2;
+
+  // Required. The application/framework-specific portion of the job.
+  oneof type_job {
+    // Job is a Hadoop job.
+    HadoopJob hadoop_job = 3;
+
+    // Job is a Spark job.
+    SparkJob spark_job = 4;
+
+    // Job is a Pyspark job.
+    PySparkJob pyspark_job = 5;
+
+    // Job is a Hive job.
+    HiveJob hive_job = 6;
+
+    // Job is a Pig job.
+    PigJob pig_job = 7;
+
+    // Job is a SparkSql job.
+    SparkSqlJob spark_sql_job = 12;
+  }
+
+  // Output only. The job status. Additional application-specific
+  // status information may be contained in the <code>type_job</code>
+  // and <code>yarn_applications</code> fields.
+  JobStatus status = 8;
+
+  // Output only. The previous job status.
+  repeated JobStatus status_history = 13;
+
+  // Output only. The collection of YARN applications spun up by this job.
+  //
+  // **Beta** Feature: This report is available for testing purposes only. It may
+  // be changed before final release.
+  repeated YarnApplication yarn_applications = 9;
+
+  // Output only. The email address of the user submitting the job. For jobs
+  // submitted on the cluster, the address is <code>username@hostname</code>.
+  string submitted_by = 10;
+
+  // Output only. A URI pointing to the location of the stdout of the job's
+  // driver program.
+  string driver_output_resource_uri = 17;
+
+  // Output only. If present, the location of miscellaneous control files
+  // which may be used as part of job setup and handling. If not present,
+  // control files may be placed in the same location as `driver_output_uri`.
+  string driver_control_files_uri = 15;
+
+  // Optional. The labels to associate with this job.
+  // Label **keys** must contain 1 to 63 characters, and must conform to
+  // [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  // Label **values** may be empty, but, if present, must contain 1 to 63
+  // characters, and must conform to [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  // No more than 32 labels can be associated with a job.
+  map<string, string> labels = 18;
+
+  // Optional. Job scheduling configuration.
+  JobScheduling scheduling = 20;
+
+  // Output only. A UUID that uniquely identifies a job within the project
+  // over time. This is in contrast to a user-settable reference.job_id that
+  // may be reused over time.
+  string job_uuid = 22;
+}
+
+// Job scheduling options.
+message JobScheduling {
+  // Optional. Maximum number of times per hour a driver may be restarted as
+  // a result of driver terminating with non-zero code before job is
+  // reported failed.
+  //
+  // A job may be reported as thrashing if driver exits with non-zero code
+  // 4 times within 10 minute window.
+  //
+  // Maximum value is 10.
+  int32 max_failures_per_hour = 1;
+}
+
+// A request to submit a job.
+message SubmitJobRequest {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The job resource.
+  Job job = 2;
+
+  // Optional. A unique id used to identify the request. If the server
+  // receives two [SubmitJobRequest][google.cloud.dataproc.v1beta2.SubmitJobRequest] requests  with the same
+  // id, then the second request will be ignored and the
+  // first [Job][google.cloud.dataproc.v1beta2.Job] created and stored in the backend
+  // is returned.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 4;
+}
+
+// A request to get the resource representation for a job in a project.
+message GetJobRequest {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The job ID.
+  string job_id = 2;
+}
+
+// A request to list jobs in a project.
+message ListJobsRequest {
+  // A matcher that specifies categories of job states.
+  enum JobStateMatcher {
+    // Match all jobs, regardless of state.
+    ALL = 0;
+
+    // Only match jobs in non-terminal states: PENDING, RUNNING, or
+    // CANCEL_PENDING.
+    ACTIVE = 1;
+
+    // Only match jobs in terminal states: CANCELLED, DONE, or ERROR.
+    NON_ACTIVE = 2;
+  }
+
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 6;
+
+  // Optional. The number of results to return in each response.
+  int32 page_size = 2;
+
+  // Optional. The page token, returned by a previous call, to request the
+  // next page of results.
+  string page_token = 3;
+
+  // Optional. If set, the returned jobs list includes only jobs that were
+  // submitted to the named cluster.
+  string cluster_name = 4;
+
+  // Optional. Specifies enumerated categories of jobs to list.
+  // (default = match ALL jobs).
+  //
+  // If `filter` is provided, `jobStateMatcher` will be ignored.
+  JobStateMatcher job_state_matcher = 5;
+
+  // Optional. A filter constraining the jobs to list. Filters are
+  // case-sensitive and have the following syntax:
+  //
+  // [field = value] AND [field [= value]] ...
+  //
+  // where **field** is `status.state` or `labels.[KEY]`, and `[KEY]` is a label
+  // key. **value** can be `*` to match all values.
+  // `status.state` can be either `ACTIVE` or `NON_ACTIVE`.
+  // Only the logical `AND` operator is supported; space-separated items are
+  // treated as having an implicit `AND` operator.
+  //
+  // Example filter:
+  //
+  // status.state = ACTIVE AND labels.env = staging AND labels.starred = *
+  string filter = 7;
+}
+
+// A request to update a job.
+message UpdateJobRequest {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 2;
+
+  // Required. The job ID.
+  string job_id = 3;
+
+  // Required. The changes to the job.
+  Job job = 4;
+
+  // Required. Specifies the path, relative to <code>Job</code>, of
+  // the field to update. For example, to update the labels of a Job the
+  // <code>update_mask</code> parameter would be specified as
+  // <code>labels</code>, and the `PATCH` request body would specify the new
+  // value. <strong>Note:</strong> Currently, <code>labels</code> is the only
+  // field that can be updated.
+  google.protobuf.FieldMask update_mask = 5;
+}
+
+// A list of jobs in a project.
+message ListJobsResponse {
+  // Output only. Jobs list.
+  repeated Job jobs = 1;
+
+  // Optional. This token is included in the response if there are more results
+  // to fetch. To fetch additional results, provide this value as the
+  // `page_token` in a subsequent <code>ListJobsRequest</code>.
+  string next_page_token = 2;
+}
+
+// A request to cancel a job.
+message CancelJobRequest {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The job ID.
+  string job_id = 2;
+}
+
+// A request to delete a job.
+message DeleteJobRequest {
+  // Required. The ID of the Google Cloud Platform project that the job
+  // belongs to.
+  string project_id = 1;
+
+  // Required. The Cloud Dataproc region in which to handle the request.
+  string region = 3;
+
+  // Required. The job ID.
+  string job_id = 2;
+}
diff --git a/dataproc/google/cloud/dataproc_v1beta2/proto/operations.proto b/dataproc/google/cloud/dataproc_v1beta2/proto/operations.proto
new file mode 100644
index 000000000000..717410832ff6
--- /dev/null
+++ b/dataproc/google/cloud/dataproc_v1beta2/proto/operations.proto
@@ -0,0 +1,84 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.dataproc.v1beta2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2;dataproc";
+option java_multiple_files = true;
+option java_outer_classname = "OperationsProto";
+option java_package = "com.google.cloud.dataproc.v1beta2";
+
+
+// The status of the operation.
+message ClusterOperationStatus {
+  // The operation state.
+  enum State {
+    // Unused.
+    UNKNOWN = 0;
+
+    // The operation has been created.
+    PENDING = 1;
+
+    // The operation is running.
+    RUNNING = 2;
+
+    // The operation is done; either cancelled or completed.
+    DONE = 3;
+  }
+
+  // Output only. A message containing the operation state.
+  State state = 1;
+
+  // Output only. A message containing the detailed operation state.
+  string inner_state = 2;
+
+  // Output only. A message containing any operation metadata details.
+  string details = 3;
+
+  // Output only. The time this state was entered.
+  google.protobuf.Timestamp state_start_time = 4;
+}
+
+// Metadata describing the operation.
+message ClusterOperationMetadata {
+  // Output only. Name of the cluster for the operation.
+  string cluster_name = 7;
+
+  // Output only. Cluster UUID for the operation.
+  string cluster_uuid = 8;
+
+  // Output only. Current operation status.
+  ClusterOperationStatus status = 9;
+
+  // Output only. The previous operation status.
+  repeated ClusterOperationStatus status_history = 10;
+
+  // Output only. The operation type.
+  string operation_type = 11;
+
+  // Output only. Short description of operation.
+  string description = 12;
+
+  // Output only. Labels associated with the operation
+  map<string, string> labels = 13;
+
+  // Output only. Errors encountered during operation execution.
+  repeated string warnings = 14;
+}
diff --git a/dataproc/google/cloud/dataproc_v1beta2/proto/shared.proto b/dataproc/google/cloud/dataproc_v1beta2/proto/shared.proto
new file mode 100644
index 000000000000..8d2f5e62834c
--- /dev/null
+++ b/dataproc/google/cloud/dataproc_v1beta2/proto/shared.proto
@@ -0,0 +1,26 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.dataproc.v1beta2;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2;dataproc";
+option java_multiple_files = true;
+option java_outer_classname = "SharedProto";
+option java_package = "com.google.cloud.dataproc.v1beta2";
+
diff --git a/dataproc/google/cloud/dataproc_v1beta2/proto/workflow_templates.proto b/dataproc/google/cloud/dataproc_v1beta2/proto/workflow_templates.proto
new file mode 100644
index 000000000000..982f874d63b1
--- /dev/null
+++ b/dataproc/google/cloud/dataproc_v1beta2/proto/workflow_templates.proto
@@ -0,0 +1,667 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.dataproc.v1beta2;
+
+import "google/api/annotations.proto";
+import "google/cloud/dataproc/v1beta2/clusters.proto";
+import "google/cloud/dataproc/v1beta2/jobs.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2;dataproc";
+option java_multiple_files = true;
+option java_outer_classname = "WorkflowTemplatesProto";
+option java_package = "com.google.cloud.dataproc.v1beta2";
+
+
+// The API interface for managing Workflow Templates in the
+// Cloud Dataproc API.
+service WorkflowTemplateService {
+  // Creates new workflow template.
+  rpc CreateWorkflowTemplate(CreateWorkflowTemplateRequest) returns (WorkflowTemplate) {
+    option (google.api.http) = {
+      post: "/v1beta2/{parent=projects/*/regions/*}/workflowTemplates"
+      body: "template"
+      additional_bindings {
+        post: "/v1beta2/{parent=projects/*/locations/*}/workflowTemplates"
+        body: "template"
+      }
+    };
+  }
+
+  // Retrieves the latest workflow template.
+  //
+  // Can retrieve previously instantiated template by specifying optional
+  // version parameter.
+  rpc GetWorkflowTemplate(GetWorkflowTemplateRequest) returns (WorkflowTemplate) {
+    option (google.api.http) = {
+      get: "/v1beta2/{name=projects/*/regions/*/workflowTemplates/*}"
+      additional_bindings {
+        get: "/v1beta2/{name=projects/*/locations/*/workflowTemplates/*}"
+      }
+    };
+  }
+
+  // Instantiates a template and begins execution.
+  //
+  // The returned Operation can be used to track execution of
+  // workflow by polling
+  // [operations.get][google.longrunning.Operations.GetOperation].
+  // The Operation will complete when entire workflow is finished.
+  //
+  // The running workflow can be aborted via
+  // [operations.cancel][google.longrunning.Operations.CancelOperation].
+  // This will cause any inflight jobs to be cancelled and workflow-owned
+  // clusters to be deleted.
+  //
+  // The [Operation.metadata][google.longrunning.Operation.metadata] will be
+  // [WorkflowMetadata][google.cloud.dataproc.v1beta2.WorkflowMetadata].
+  //
+  // On successful completion,
+  // [Operation.response][google.longrunning.Operation.response] will be
+  // [Empty][google.protobuf.Empty].
+  rpc InstantiateWorkflowTemplate(InstantiateWorkflowTemplateRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta2/{name=projects/*/regions/*/workflowTemplates/*}:instantiate"
+      body: "*"
+      additional_bindings {
+        post: "/v1beta2/{name=projects/*/locations/*/workflowTemplates/*}:instantiate"
+        body: "*"
+      }
+    };
+  }
+
+  // Instantiates a template and begins execution.
+  //
+  // This method is equivalent to executing the sequence
+  // [CreateWorkflowTemplate][google.cloud.dataproc.v1beta2.WorkflowTemplateService.CreateWorkflowTemplate], [InstantiateWorkflowTemplate][google.cloud.dataproc.v1beta2.WorkflowTemplateService.InstantiateWorkflowTemplate],
+  // [DeleteWorkflowTemplate][google.cloud.dataproc.v1beta2.WorkflowTemplateService.DeleteWorkflowTemplate].
+  //
+  // The returned Operation can be used to track execution of
+  // workflow by polling
+  // [operations.get][google.longrunning.Operations.GetOperation].
+  // The Operation will complete when entire workflow is finished.
+  //
+  // The running workflow can be aborted via
+  // [operations.cancel][google.longrunning.Operations.CancelOperation].
+  // This will cause any inflight jobs to be cancelled and workflow-owned
+  // clusters to be deleted.
+  //
+  // The [Operation.metadata][google.longrunning.Operation.metadata] will be
+  // [WorkflowMetadata][google.cloud.dataproc.v1beta2.WorkflowMetadata].
+  //
+  // On successful completion,
+  // [Operation.response][google.longrunning.Operation.response] will be
+  // [Empty][google.protobuf.Empty].
+  rpc InstantiateInlineWorkflowTemplate(InstantiateInlineWorkflowTemplateRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta2/{parent=projects/*/locations/*}/workflowTemplates:instantiateInline"
+      body: "template"
+      additional_bindings {
+        post: "/v1beta2/{parent=projects/*/regions/*}/workflowTemplates:instantiateInline"
+        body: "template"
+      }
+    };
+  }
+
+  // Updates (replaces) workflow template. The updated template
+  // must contain version that matches the current server version.
+  rpc UpdateWorkflowTemplate(UpdateWorkflowTemplateRequest) returns (WorkflowTemplate) {
+    option (google.api.http) = {
+      put: "/v1beta2/{template.name=projects/*/regions/*/workflowTemplates/*}"
+      body: "template"
+      additional_bindings {
+        put: "/v1beta2/{template.name=projects/*/locations/*/workflowTemplates/*}"
+        body: "template"
+      }
+    };
+  }
+
+  // Lists workflows that match the specified filter in the request.
+  rpc ListWorkflowTemplates(ListWorkflowTemplatesRequest) returns (ListWorkflowTemplatesResponse) {
+    option (google.api.http) = {
+      get: "/v1beta2/{parent=projects/*/regions/*}/workflowTemplates"
+      additional_bindings {
+        get: "/v1beta2/{parent=projects/*/locations/*}/workflowTemplates"
+      }
+    };
+  }
+
+  // Deletes a workflow template. It does not cancel in-progress workflows.
+  rpc DeleteWorkflowTemplate(DeleteWorkflowTemplateRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1beta2/{name=projects/*/regions/*/workflowTemplates/*}"
+      additional_bindings {
+        delete: "/v1beta2/{name=projects/*/locations/*/workflowTemplates/*}"
+      }
+    };
+  }
+}
+
+// A Cloud Dataproc workflow template resource.
+message WorkflowTemplate {
+  // Required. The template id.
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). Cannot begin or end with underscore
+  // or hyphen. Must consist of between 3 and 50 characters.
+  string id = 2;
+
+  // Output only. The "resource name" of the template, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}/workflowTemplates/{template_id}`
+  string name = 1;
+
+  // Optional. Used to perform a consistent read-modify-write.
+  //
+  // This field should be left blank for a `CreateWorkflowTemplate` request. It
+  // is required for an `UpdateWorkflowTemplate` request, and must match the
+  // current server version. A typical update template flow would fetch the
+  // current template with a `GetWorkflowTemplate` request, which will return
+  // the current template with the `version` field filled in with the
+  // current server version. The user updates other fields in the template,
+  // then returns it as part of the `UpdateWorkflowTemplate` request.
+  int32 version = 3;
+
+  // Output only. The time template was created.
+  google.protobuf.Timestamp create_time = 4;
+
+  // Output only. The time template was last updated.
+  google.protobuf.Timestamp update_time = 5;
+
+  // Optional. The labels to associate with this template. These labels
+  // will be propagated to all jobs and clusters created by the workflow
+  // instance.
+  //
+  // Label **keys** must contain 1 to 63 characters, and must conform to
+  // [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  //
+  // Label **values** may be empty, but, if present, must contain 1 to 63
+  // characters, and must conform to
+  // [RFC 1035](https://www.ietf.org/rfc/rfc1035.txt).
+  //
+  // No more than 32 labels can be associated with a template.
+  map<string, string> labels = 6;
+
+  // Required. WorkflowTemplate scheduling information.
+  WorkflowTemplatePlacement placement = 7;
+
+  // Required. The Directed Acyclic Graph of Jobs to submit.
+  repeated OrderedJob jobs = 8;
+
+  // Optional. Template parameters whose values are substituted into the
+  // template. Values for parameters must be provided when the template is
+  // instantiated.
+  repeated TemplateParameter parameters = 9;
+}
+
+// Specifies workflow execution target.
+//
+// Either `managed_cluster` or `cluster_selector` is required.
+message WorkflowTemplatePlacement {
+  // Required. Specifies where workflow executes; either on a managed
+  // cluster or an existing cluster chosen by labels.
+  oneof placement {
+    // Optional. A cluster that is managed by the workflow.
+    ManagedCluster managed_cluster = 1;
+
+    // Optional. A selector that chooses target cluster for jobs based
+    // on metadata.
+    //
+    // The selector is evaluated at the time each job is submitted.
+    ClusterSelector cluster_selector = 2;
+  }
+}
+
+// Cluster that is managed by the workflow.
+message ManagedCluster {
+  // Required. The cluster name prefix. A unique cluster name will be formed by
+  // appending a random suffix.
+  //
+  // The name must contain only lower-case letters (a-z), numbers (0-9),
+  // and hyphens (-). Must begin with a letter. Cannot begin or end with
+  // hyphen. Must consist of between 2 and 35 characters.
+  string cluster_name = 2;
+
+  // Required. The cluster configuration.
+  ClusterConfig config = 3;
+
+  // Optional. The labels to associate with this cluster.
+  //
+  // Label keys must be between 1 and 63 characters long, and must conform to
+  // the following PCRE regular expression:
+  // [\p{Ll}\p{Lo}][\p{Ll}\p{Lo}\p{N}_-]{0,62}
+  //
+  // Label values must be between 1 and 63 characters long, and must conform to
+  // the following PCRE regular expression: [\p{Ll}\p{Lo}\p{N}_-]{0,63}
+  //
+  // No more than 32 labels can be associated with a given cluster.
+  map<string, string> labels = 4;
+}
+
+// A selector that chooses target cluster for jobs based on metadata.
+message ClusterSelector {
+  // Optional. The zone where workflow process executes. This parameter does not
+  // affect the selection of the cluster.
+  //
+  // If unspecified, the zone of the first cluster matching the selector
+  // is used.
+  string zone = 1;
+
+  // Required. The cluster labels. Cluster must have all labels
+  // to match.
+  map<string, string> cluster_labels = 2;
+}
+
+// A job executed by the workflow.
+message OrderedJob {
+  // Required. The step id. The id must be unique among all jobs
+  // within the template.
+  //
+  // The step id is used as prefix for job id, as job
+  // `goog-dataproc-workflow-step-id` label, and in
+  // [prerequisiteStepIds][google.cloud.dataproc.v1beta2.OrderedJob.prerequisite_step_ids] field from other
+  // steps.
+  //
+  // The id must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). Cannot begin or end with underscore
+  // or hyphen. Must consist of between 3 and 50 characters.
+  string step_id = 1;
+
+  // Required. The job definition.
+  oneof job_type {
+    // Job is a Hadoop job.
+    HadoopJob hadoop_job = 2;
+
+    // Job is a Spark job.
+    SparkJob spark_job = 3;
+
+    // Job is a Pyspark job.
+    PySparkJob pyspark_job = 4;
+
+    // Job is a Hive job.
+    HiveJob hive_job = 5;
+
+    // Job is a Pig job.
+    PigJob pig_job = 6;
+
+    // Job is a SparkSql job.
+    SparkSqlJob spark_sql_job = 7;
+  }
+
+  // Optional. The labels to associate with this job.
+  //
+  // Label keys must be between 1 and 63 characters long, and must conform to
+  // the following regular expression:
+  // [\p{Ll}\p{Lo}][\p{Ll}\p{Lo}\p{N}_-]{0,62}
+  //
+  // Label values must be between 1 and 63 characters long, and must conform to
+  // the following regular expression: [\p{Ll}\p{Lo}\p{N}_-]{0,63}
+  //
+  // No more than 32 labels can be associated with a given job.
+  map<string, string> labels = 8;
+
+  // Optional. Job scheduling configuration.
+  JobScheduling scheduling = 9;
+
+  // Optional. The optional list of prerequisite job step_ids.
+  // If not specified, the job will start at the beginning of workflow.
+  repeated string prerequisite_step_ids = 10;
+}
+
+// A configurable parameter that replaces one or more fields in the template.
+// Parameterizable fields:
+// - Labels
+// - File uris
+// - Job properties
+// - Job arguments
+// - Script variables
+// - Main class (in HadoopJob and SparkJob)
+// - Zone (in ClusterSelector)
+message TemplateParameter {
+  // Required.  Parameter name.
+  // The parameter name is used as the key, and paired with the
+  // parameter value, which are passed to the template when the template
+  // is instantiated.
+  // The name must contain only capital letters (A-Z), numbers (0-9), and
+  // underscores (_), and must not start with a number. The maximum length is
+  // 40 characters.
+  string name = 1;
+
+  // Required. Paths to all fields that the parameter replaces.
+  // A field is allowed to appear in at most one parameter's list of field paths.
+  //
+  // A field path is similar in syntax to a [google.protobuf.FieldMask][google.protobuf.FieldMask].
+  // For example, a field path that references the zone field of a workflow
+  // template's cluster selector would be specified as
+  // `placement.clusterSelector.zone`.
+  //
+  // Also, field paths can reference fields using the following syntax:
+  //
+  // * Values in maps can be referenced by key:
+  //     * labels['key']
+  //     * placement.clusterSelector.clusterLabels['key']
+  //     * placement.managedCluster.labels['key']
+  //     * placement.clusterSelector.clusterLabels['key']
+  //     * jobs['step-id'].labels['key']
+  //
+  // * Jobs in the jobs list can be referenced by step-id:
+  //     * jobs['step-id'].hadoopJob.mainJarFileUri
+  //     * jobs['step-id'].hiveJob.queryFileUri
+  //     * jobs['step-id'].pySparkJob.mainPythonFileUri
+  //     * jobs['step-id'].hadoopJob.jarFileUris[0]
+  //     * jobs['step-id'].hadoopJob.archiveUris[0]
+  //     * jobs['step-id'].hadoopJob.fileUris[0]
+  //     * jobs['step-id'].pySparkJob.pythonFileUris[0]
+  //
+  // * Items in repeated fields can be referenced by a zero-based index:
+  //     * jobs['step-id'].sparkJob.args[0]
+  //
+  // * Other examples:
+  //     * jobs['step-id'].hadoopJob.properties['key']
+  //     * jobs['step-id'].hadoopJob.args[0]
+  //     * jobs['step-id'].hiveJob.scriptVariables['key']
+  //     * jobs['step-id'].hadoopJob.mainJarFileUri
+  //     * placement.clusterSelector.zone
+  //
+  // It may not be possible to parameterize maps and repeated fields in their
+  // entirety since only individual map values and individual items in repeated
+  // fields can be referenced. For example, the following field paths are
+  // invalid:
+  //
+  // - placement.clusterSelector.clusterLabels
+  // - jobs['step-id'].sparkJob.args
+  repeated string fields = 2;
+
+  // Optional. Brief description of the parameter.
+  // Must not exceed 1024 characters.
+  string description = 3;
+
+  // Optional. Validation rules to be applied to this parameter's value.
+  ParameterValidation validation = 4;
+}
+
+// Configuration for parameter validation.
+message ParameterValidation {
+  // Required. The type of validation to be performed.
+  oneof validation_type {
+    // Validation based on regular expressions.
+    RegexValidation regex = 1;
+
+    // Validation based on a list of allowed values.
+    ValueValidation values = 2;
+  }
+}
+
+// Validation based on regular expressions.
+message RegexValidation {
+  // Required. RE2 regular expressions used to validate the parameter's value.
+  // The value must match the regex in its entirety (substring
+  // matches are not sufficient).
+  repeated string regexes = 1;
+}
+
+// Validation based on a list of allowed values.
+message ValueValidation {
+  // Required. List of allowed values for the parameter.
+  repeated string values = 1;
+}
+
+// A Cloud Dataproc workflow template resource.
+message WorkflowMetadata {
+  // The operation state.
+  enum State {
+    // Unused.
+    UNKNOWN = 0;
+
+    // The operation has been created.
+    PENDING = 1;
+
+    // The operation is running.
+    RUNNING = 2;
+
+    // The operation is done; either cancelled or completed.
+    DONE = 3;
+  }
+
+  // Output only. The "resource name" of the template.
+  string template = 1;
+
+  // Output only. The version of template at the time of
+  // workflow instantiation.
+  int32 version = 2;
+
+  // Output only. The create cluster operation metadata.
+  ClusterOperation create_cluster = 3;
+
+  // Output only. The workflow graph.
+  WorkflowGraph graph = 4;
+
+  // Output only. The delete cluster operation metadata.
+  ClusterOperation delete_cluster = 5;
+
+  // Output only. The workflow state.
+  State state = 6;
+
+  // Output only. The name of the target cluster.
+  string cluster_name = 7;
+
+  // Map from parameter names to values that were used for those parameters.
+  map<string, string> parameters = 8;
+
+  // Output only. Workflow start time.
+  google.protobuf.Timestamp start_time = 9;
+
+  // Output only. Workflow end time.
+  google.protobuf.Timestamp end_time = 10;
+
+  // Output only. The UUID of target cluster.
+  string cluster_uuid = 11;
+}
+
+// The cluster operation triggered by a workflow.
+message ClusterOperation {
+  // Output only. The id of the cluster operation.
+  string operation_id = 1;
+
+  // Output only. Error, if operation failed.
+  string error = 2;
+
+  // Output only. Indicates the operation is done.
+  bool done = 3;
+}
+
+// The workflow graph.
+message WorkflowGraph {
+  // Output only. The workflow nodes.
+  repeated WorkflowNode nodes = 1;
+}
+
+// The workflow node.
+message WorkflowNode {
+  // The workflow node state.
+  enum NodeState {
+    // State is unspecified.
+    NODE_STATUS_UNSPECIFIED = 0;
+
+    // The node is awaiting prerequisite node to finish.
+    BLOCKED = 1;
+
+    // The node is runnable but not running.
+    RUNNABLE = 2;
+
+    // The node is running.
+    RUNNING = 3;
+
+    // The node completed successfully.
+    COMPLETED = 4;
+
+    // The node failed. A node can be marked FAILED because
+    // its ancestor or peer failed.
+    FAILED = 5;
+  }
+
+  // Output only. The name of the node.
+  string step_id = 1;
+
+  // Output only. Node's prerequisite nodes.
+  repeated string prerequisite_step_ids = 2;
+
+  // Output only. The job id; populated after the node enters RUNNING state.
+  string job_id = 3;
+
+  // Output only. The node state.
+  NodeState state = 5;
+
+  // Output only. The error detail.
+  string error = 6;
+}
+
+// A request to create a workflow template.
+message CreateWorkflowTemplateRequest {
+  // Required. The "resource name" of the region, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}`
+  string parent = 1;
+
+  // Required. The Dataproc workflow template to create.
+  WorkflowTemplate template = 2;
+}
+
+// A request to fetch a workflow template.
+message GetWorkflowTemplateRequest {
+  // Required. The "resource name" of the workflow template, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}/workflowTemplates/{template_id}`
+  string name = 1;
+
+  // Optional. The version of workflow template to retrieve. Only previously
+  // instatiated versions can be retrieved.
+  //
+  // If unspecified, retrieves the current version.
+  int32 version = 2;
+}
+
+// A request to instantiate a workflow template.
+message InstantiateWorkflowTemplateRequest {
+  // Required. The "resource name" of the workflow template, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}/workflowTemplates/{template_id}`
+  string name = 1;
+
+  // Optional. The version of workflow template to instantiate. If specified,
+  // the workflow will be instantiated only if the current version of
+  // the workflow template has the supplied version.
+  //
+  // This option cannot be used to instantiate a previous version of
+  // workflow template.
+  int32 version = 2;
+
+  // Deprecated. Please use `request_id` field instead.
+  string instance_id = 3 [deprecated = true];
+
+  // Optional. A tag that prevents multiple concurrent workflow
+  // instances with the same tag from running. This mitigates risk of
+  // concurrent instances started due to retries.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The tag must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 5;
+
+  // Optional. Map from parameter names to values that should be used for those
+  // parameters. Values may not exceed 100 characters.
+  map<string, string> parameters = 4;
+}
+
+// A request to instantiate an inline workflow template.
+message InstantiateInlineWorkflowTemplateRequest {
+  // Required. The "resource name" of the workflow template region, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}`
+  string parent = 1;
+
+  // Required. The workflow template to instantiate.
+  WorkflowTemplate template = 2;
+
+  // Deprecated. Please use `request_id` field instead.
+  string instance_id = 3;
+
+  // Optional. A tag that prevents multiple concurrent workflow
+  // instances with the same tag from running. This mitigates risk of
+  // concurrent instances started due to retries.
+  //
+  // It is recommended to always set this value to a
+  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
+  //
+  // The tag must contain only letters (a-z, A-Z), numbers (0-9),
+  // underscores (_), and hyphens (-). The maximum length is 40 characters.
+  string request_id = 4;
+}
+
+// A request to update a workflow template.
+message UpdateWorkflowTemplateRequest {
+  // Required. The updated workflow template.
+  //
+  // The `template.version` field must match the current version.
+  WorkflowTemplate template = 1;
+}
+
+// A request to list workflow templates in a project.
+message ListWorkflowTemplatesRequest {
+  // Required. The "resource name" of the region, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}`
+  string parent = 1;
+
+  // Optional. The maximum number of results to return in each response.
+  int32 page_size = 2;
+
+  // Optional. The page token, returned by a previous call, to request the
+  // next page of results.
+  string page_token = 3;
+}
+
+// A response to a request to list workflow templates in a project.
+message ListWorkflowTemplatesResponse {
+  // Output only. WorkflowTemplates list.
+  repeated WorkflowTemplate templates = 1;
+
+  // Output only. This token is included in the response if there are more results
+  // to fetch. To fetch additional results, provide this value as the
+  // page_token in a subsequent <code>ListWorkflowTemplatesRequest</code>.
+  string next_page_token = 2;
+}
+
+// A request to delete a workflow template.
+//
+// Currently started workflows will remain running.
+message DeleteWorkflowTemplateRequest {
+  // Required. The "resource name" of the workflow template, as described
+  // in https://cloud.google.com/apis/design/resource_names of the form
+  // `projects/{project_id}/regions/{region}/workflowTemplates/{template_id}`
+  string name = 1;
+
+  // Optional. The version of workflow template to delete. If specified,
+  // will only delete the template if the current server version matches
+  // specified version.
+  int32 version = 2;
+}
diff --git a/dataproc/synth.metadata b/dataproc/synth.metadata
index ec8bbddb758d..99381a2e902e 100644
--- a/dataproc/synth.metadata
+++ b/dataproc/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:16:17.473035Z",
+  "updateTime": "2019-01-23T22:52:53.418719Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/dataproc/synth.py b/dataproc/synth.py
index d38f35499912..a2c50b0e4a86 100644
--- a/dataproc/synth.py
+++ b/dataproc/synth.py
@@ -27,7 +27,7 @@
 # Generate dataproc GAPIC layer
 # ----------------------------------------------------------------------------
 for version in versions:
-    library = gapic.py_library("dataproc", version)
+    library = gapic.py_library("dataproc", version, include_protos=True,)
     s.move(library, excludes=["docs/index.rst", "nox.py", "README.rst", "setup.py"])
 
     s.replace(
diff --git a/datastore/google/cloud/datastore_v1/proto/datastore.proto b/datastore/google/cloud/datastore_v1/proto/datastore.proto
new file mode 100644
index 000000000000..2a29a58cec72
--- /dev/null
+++ b/datastore/google/cloud/datastore_v1/proto/datastore.proto
@@ -0,0 +1,395 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.datastore.v1;
+
+import "google/api/annotations.proto";
+import "google/datastore/v1/entity.proto";
+import "google/datastore/v1/query.proto";
+
+option csharp_namespace = "Google.Cloud.Datastore.V1";
+option go_package = "google.golang.org/genproto/googleapis/datastore/v1;datastore";
+option java_multiple_files = true;
+option java_outer_classname = "DatastoreProto";
+option java_package = "com.google.datastore.v1";
+option php_namespace = "Google\\Cloud\\Datastore\\V1";
+
+
+// Each RPC normalizes the partition IDs of the keys in its input entities,
+// and always returns entities with keys with normalized partition IDs.
+// This applies to all keys and entities, including those in values, except keys
+// with both an empty path and an empty or unset partition ID. Normalization of
+// input keys sets the project ID (if not already set) to the project ID from
+// the request.
+//
+service Datastore {
+  // Looks up entities by key.
+  rpc Lookup(LookupRequest) returns (LookupResponse) {
+    option (google.api.http) = {
+      post: "/v1/projects/{project_id}:lookup"
+      body: "*"
+    };
+  }
+
+  // Queries for entities.
+  rpc RunQuery(RunQueryRequest) returns (RunQueryResponse) {
+    option (google.api.http) = {
+      post: "/v1/projects/{project_id}:runQuery"
+      body: "*"
+    };
+  }
+
+  // Begins a new transaction.
+  rpc BeginTransaction(BeginTransactionRequest) returns (BeginTransactionResponse) {
+    option (google.api.http) = {
+      post: "/v1/projects/{project_id}:beginTransaction"
+      body: "*"
+    };
+  }
+
+  // Commits a transaction, optionally creating, deleting or modifying some
+  // entities.
+  rpc Commit(CommitRequest) returns (CommitResponse) {
+    option (google.api.http) = {
+      post: "/v1/projects/{project_id}:commit"
+      body: "*"
+    };
+  }
+
+  // Rolls back a transaction.
+  rpc Rollback(RollbackRequest) returns (RollbackResponse) {
+    option (google.api.http) = {
+      post: "/v1/projects/{project_id}:rollback"
+      body: "*"
+    };
+  }
+
+  // Allocates IDs for the given keys, which is useful for referencing an entity
+  // before it is inserted.
+  rpc AllocateIds(AllocateIdsRequest) returns (AllocateIdsResponse) {
+    option (google.api.http) = {
+      post: "/v1/projects/{project_id}:allocateIds"
+      body: "*"
+    };
+  }
+
+  // Prevents the supplied keys' IDs from being auto-allocated by Cloud
+  // Datastore.
+  rpc ReserveIds(ReserveIdsRequest) returns (ReserveIdsResponse) {
+    option (google.api.http) = {
+      post: "/v1/projects/{project_id}:reserveIds"
+      body: "*"
+    };
+  }
+}
+
+// The request for [Datastore.Lookup][google.datastore.v1.Datastore.Lookup].
+message LookupRequest {
+  // The ID of the project against which to make the request.
+  string project_id = 8;
+
+  // The options for this lookup request.
+  ReadOptions read_options = 1;
+
+  // Keys of entities to look up.
+  repeated Key keys = 3;
+}
+
+// The response for [Datastore.Lookup][google.datastore.v1.Datastore.Lookup].
+message LookupResponse {
+  // Entities found as `ResultType.FULL` entities. The order of results in this
+  // field is undefined and has no relation to the order of the keys in the
+  // input.
+  repeated EntityResult found = 1;
+
+  // Entities not found as `ResultType.KEY_ONLY` entities. The order of results
+  // in this field is undefined and has no relation to the order of the keys
+  // in the input.
+  repeated EntityResult missing = 2;
+
+  // A list of keys that were not looked up due to resource constraints. The
+  // order of results in this field is undefined and has no relation to the
+  // order of the keys in the input.
+  repeated Key deferred = 3;
+}
+
+// The request for [Datastore.RunQuery][google.datastore.v1.Datastore.RunQuery].
+message RunQueryRequest {
+  // The ID of the project against which to make the request.
+  string project_id = 8;
+
+  // Entities are partitioned into subsets, identified by a partition ID.
+  // Queries are scoped to a single partition.
+  // This partition ID is normalized with the standard default context
+  // partition ID.
+  PartitionId partition_id = 2;
+
+  // The options for this query.
+  ReadOptions read_options = 1;
+
+  // The type of query.
+  oneof query_type {
+    // The query to run.
+    Query query = 3;
+
+    // The GQL query to run.
+    GqlQuery gql_query = 7;
+  }
+}
+
+// The response for [Datastore.RunQuery][google.datastore.v1.Datastore.RunQuery].
+message RunQueryResponse {
+  // A batch of query results (always present).
+  QueryResultBatch batch = 1;
+
+  // The parsed form of the `GqlQuery` from the request, if it was set.
+  Query query = 2;
+}
+
+// The request for [Datastore.BeginTransaction][google.datastore.v1.Datastore.BeginTransaction].
+message BeginTransactionRequest {
+  // The ID of the project against which to make the request.
+  string project_id = 8;
+
+  // Options for a new transaction.
+  TransactionOptions transaction_options = 10;
+}
+
+// The response for [Datastore.BeginTransaction][google.datastore.v1.Datastore.BeginTransaction].
+message BeginTransactionResponse {
+  // The transaction identifier (always present).
+  bytes transaction = 1;
+}
+
+// The request for [Datastore.Rollback][google.datastore.v1.Datastore.Rollback].
+message RollbackRequest {
+  // The ID of the project against which to make the request.
+  string project_id = 8;
+
+  // The transaction identifier, returned by a call to
+  // [Datastore.BeginTransaction][google.datastore.v1.Datastore.BeginTransaction].
+  bytes transaction = 1;
+}
+
+// The response for [Datastore.Rollback][google.datastore.v1.Datastore.Rollback].
+// (an empty message).
+message RollbackResponse {
+
+}
+
+// The request for [Datastore.Commit][google.datastore.v1.Datastore.Commit].
+message CommitRequest {
+  // The modes available for commits.
+  enum Mode {
+    // Unspecified. This value must not be used.
+    MODE_UNSPECIFIED = 0;
+
+    // Transactional: The mutations are either all applied, or none are applied.
+    // Learn about transactions [here](https://cloud.google.com/datastore/docs/concepts/transactions).
+    TRANSACTIONAL = 1;
+
+    // Non-transactional: The mutations may not apply as all or none.
+    NON_TRANSACTIONAL = 2;
+  }
+
+  // The ID of the project against which to make the request.
+  string project_id = 8;
+
+  // The type of commit to perform. Defaults to `TRANSACTIONAL`.
+  Mode mode = 5;
+
+  // Must be set when mode is `TRANSACTIONAL`.
+  oneof transaction_selector {
+    // The identifier of the transaction associated with the commit. A
+    // transaction identifier is returned by a call to
+    // [Datastore.BeginTransaction][google.datastore.v1.Datastore.BeginTransaction].
+    bytes transaction = 1;
+  }
+
+  // The mutations to perform.
+  //
+  // When mode is `TRANSACTIONAL`, mutations affecting a single entity are
+  // applied in order. The following sequences of mutations affecting a single
+  // entity are not permitted in a single `Commit` request:
+  //
+  // - `insert` followed by `insert`
+  // - `update` followed by `insert`
+  // - `upsert` followed by `insert`
+  // - `delete` followed by `update`
+  //
+  // When mode is `NON_TRANSACTIONAL`, no two mutations may affect a single
+  // entity.
+  repeated Mutation mutations = 6;
+}
+
+// The response for [Datastore.Commit][google.datastore.v1.Datastore.Commit].
+message CommitResponse {
+  // The result of performing the mutations.
+  // The i-th mutation result corresponds to the i-th mutation in the request.
+  repeated MutationResult mutation_results = 3;
+
+  // The number of index entries updated during the commit, or zero if none were
+  // updated.
+  int32 index_updates = 4;
+}
+
+// The request for [Datastore.AllocateIds][google.datastore.v1.Datastore.AllocateIds].
+message AllocateIdsRequest {
+  // The ID of the project against which to make the request.
+  string project_id = 8;
+
+  // A list of keys with incomplete key paths for which to allocate IDs.
+  // No key may be reserved/read-only.
+  repeated Key keys = 1;
+}
+
+// The response for [Datastore.AllocateIds][google.datastore.v1.Datastore.AllocateIds].
+message AllocateIdsResponse {
+  // The keys specified in the request (in the same order), each with
+  // its key path completed with a newly allocated ID.
+  repeated Key keys = 1;
+}
+
+// The request for [Datastore.ReserveIds][google.datastore.v1.Datastore.ReserveIds].
+message ReserveIdsRequest {
+  // The ID of the project against which to make the request.
+  string project_id = 8;
+
+  // If not empty, the ID of the database against which to make the request.
+  string database_id = 9;
+
+  // A list of keys with complete key paths whose numeric IDs should not be
+  // auto-allocated.
+  repeated Key keys = 1;
+}
+
+// The response for [Datastore.ReserveIds][google.datastore.v1.Datastore.ReserveIds].
+message ReserveIdsResponse {
+
+}
+
+// A mutation to apply to an entity.
+message Mutation {
+  // The mutation operation.
+  //
+  // For `insert`, `update`, and `upsert`:
+  // - The entity's key must not be reserved/read-only.
+  // - No property in the entity may have a reserved name,
+  //   not even a property in an entity in a value.
+  // - No value in the entity may have meaning 18,
+  //   not even a value in an entity in another value.
+  oneof operation {
+    // The entity to insert. The entity must not already exist.
+    // The entity key's final path element may be incomplete.
+    Entity insert = 4;
+
+    // The entity to update. The entity must already exist.
+    // Must have a complete key path.
+    Entity update = 5;
+
+    // The entity to upsert. The entity may or may not already exist.
+    // The entity key's final path element may be incomplete.
+    Entity upsert = 6;
+
+    // The key of the entity to delete. The entity may or may not already exist.
+    // Must have a complete key path and must not be reserved/read-only.
+    Key delete = 7;
+  }
+
+  // When set, the server will detect whether or not this mutation conflicts
+  // with the current version of the entity on the server. Conflicting mutations
+  // are not applied, and are marked as such in MutationResult.
+  oneof conflict_detection_strategy {
+    // The version of the entity that this mutation is being applied to. If this
+    // does not match the current version on the server, the mutation conflicts.
+    int64 base_version = 8;
+  }
+}
+
+// The result of applying a mutation.
+message MutationResult {
+  // The automatically allocated key.
+  // Set only when the mutation allocated a key.
+  Key key = 3;
+
+  // The version of the entity on the server after processing the mutation. If
+  // the mutation doesn't change anything on the server, then the version will
+  // be the version of the current entity or, if no entity is present, a version
+  // that is strictly greater than the version of any previous entity and less
+  // than the version of any possible future entity.
+  int64 version = 4;
+
+  // Whether a conflict was detected for this mutation. Always false when a
+  // conflict detection strategy field is not set in the mutation.
+  bool conflict_detected = 5;
+}
+
+// The options shared by read requests.
+message ReadOptions {
+  // The possible values for read consistencies.
+  enum ReadConsistency {
+    // Unspecified. This value must not be used.
+    READ_CONSISTENCY_UNSPECIFIED = 0;
+
+    // Strong consistency.
+    STRONG = 1;
+
+    // Eventual consistency.
+    EVENTUAL = 2;
+  }
+
+  // If not specified, lookups and ancestor queries default to
+  // `read_consistency`=`STRONG`, global queries default to
+  // `read_consistency`=`EVENTUAL`.
+  oneof consistency_type {
+    // The non-transactional read consistency to use.
+    // Cannot be set to `STRONG` for global queries.
+    ReadConsistency read_consistency = 1;
+
+    // The identifier of the transaction in which to read. A
+    // transaction identifier is returned by a call to
+    // [Datastore.BeginTransaction][google.datastore.v1.Datastore.BeginTransaction].
+    bytes transaction = 2;
+  }
+}
+
+// Options for beginning a new transaction.
+//
+// Transactions can be created explicitly with calls to
+// [Datastore.BeginTransaction][google.datastore.v1.Datastore.BeginTransaction] or implicitly by setting
+// [ReadOptions.new_transaction][google.datastore.v1.ReadOptions.new_transaction] in read requests.
+message TransactionOptions {
+  // Options specific to read / write transactions.
+  message ReadWrite {
+    // The transaction identifier of the transaction being retried.
+    bytes previous_transaction = 1;
+  }
+
+  // Options specific to read-only transactions.
+  message ReadOnly {
+
+  }
+
+  // The `mode` of the transaction, indicating whether write operations are
+  // supported.
+  oneof mode {
+    // The transaction should allow both reads and writes.
+    ReadWrite read_write = 1;
+
+    // The transaction should only allow reads.
+    ReadOnly read_only = 2;
+  }
+}
diff --git a/datastore/google/cloud/datastore_v1/proto/datastore_admin.proto b/datastore/google/cloud/datastore_v1/proto/datastore_admin.proto
new file mode 100644
index 000000000000..c730de79c0f3
--- /dev/null
+++ b/datastore/google/cloud/datastore_v1/proto/datastore_admin.proto
@@ -0,0 +1,329 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.datastore.admin.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Datastore.Admin.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/datastore/admin/v1beta1;admin";
+option java_multiple_files = true;
+option java_outer_classname = "DatastoreAdminProto";
+option java_package = "com.google.datastore.admin.v1beta1";
+
+
+// Google Cloud Datastore Admin API
+//
+// The Datastore Admin API provides several admin services for Cloud Datastore.
+//
+// -----------------------------------------------------------------------------
+// ## Concepts
+//
+// Project, namespace, kind, and entity as defined in the Google Cloud Datastore
+// API.
+//
+// Operation: An Operation represents work being performed in the background.
+//
+// EntityFilter: Allows specifying a subset of entities in a project. This is
+// specified as a combination of kinds and namespaces (either or both of which
+// may be all).
+//
+// -----------------------------------------------------------------------------
+// ## Services
+//
+// # Export/Import
+//
+// The Export/Import service provides the ability to copy all or a subset of
+// entities to/from Google Cloud Storage.
+//
+// Exported data may be imported into Cloud Datastore for any Google Cloud
+// Platform project. It is not restricted to the export source project. It is
+// possible to export from one project and then import into another.
+//
+// Exported data can also be loaded into Google BigQuery for analysis.
+//
+// Exports and imports are performed asynchronously. An Operation resource is
+// created for each export/import. The state (including any errors encountered)
+// of the export/import may be queried via the Operation resource.
+//
+// # Operation
+//
+// The Operations collection provides a record of actions performed for the
+// specified project (including any operations in progress). Operations are not
+// created directly but through calls on other collections or resources.
+//
+// An operation that is not yet done may be cancelled. The request to cancel is
+// asynchronous and the operation may continue to run for some time after the
+// request to cancel is made.
+//
+// An operation that is done may be deleted so that it is no longer listed as
+// part of the Operation collection.
+//
+// ListOperations returns all pending operations, but not completed operations.
+//
+// Operations are created by service DatastoreAdmin,
+// but are accessed via service google.longrunning.Operations.
+service DatastoreAdmin {
+  // Exports a copy of all or a subset of entities from Google Cloud Datastore
+  // to another storage system, such as Google Cloud Storage. Recent updates to
+  // entities may not be reflected in the export. The export occurs in the
+  // background and its progress can be monitored and managed via the
+  // Operation resource that is created. The output of an export may only be
+  // used once the associated operation is done. If an export operation is
+  // cancelled before completion it may leave partial data behind in Google
+  // Cloud Storage.
+  rpc ExportEntities(ExportEntitiesRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta1/projects/{project_id}:export"
+      body: "*"
+    };
+  }
+
+  // Imports entities into Google Cloud Datastore. Existing entities with the
+  // same key are overwritten. The import occurs in the background and its
+  // progress can be monitored and managed via the Operation resource that is
+  // created. If an ImportEntities operation is cancelled, it is possible
+  // that a subset of the data has already been imported to Cloud Datastore.
+  rpc ImportEntities(ImportEntitiesRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta1/projects/{project_id}:import"
+      body: "*"
+    };
+  }
+}
+
+// Metadata common to all Datastore Admin operations.
+message CommonMetadata {
+  // The various possible states for an ongoing Operation.
+  enum State {
+    // Unspecified.
+    STATE_UNSPECIFIED = 0;
+
+    // Request is being prepared for processing.
+    INITIALIZING = 1;
+
+    // Request is actively being processed.
+    PROCESSING = 2;
+
+    // Request is in the process of being cancelled after user called
+    // google.longrunning.Operations.CancelOperation on the operation.
+    CANCELLING = 3;
+
+    // Request has been processed and is in its finalization stage.
+    FINALIZING = 4;
+
+    // Request has completed successfully.
+    SUCCESSFUL = 5;
+
+    // Request has finished being processed, but encountered an error.
+    FAILED = 6;
+
+    // Request has finished being cancelled after user called
+    // google.longrunning.Operations.CancelOperation.
+    CANCELLED = 7;
+  }
+
+  // The time that work began on the operation.
+  google.protobuf.Timestamp start_time = 1;
+
+  // The time the operation ended, either successfully or otherwise.
+  google.protobuf.Timestamp end_time = 2;
+
+  // The type of the operation. Can be used as a filter in
+  // ListOperationsRequest.
+  OperationType operation_type = 3;
+
+  // The client-assigned labels which were provided when the operation was
+  // created. May also include additional labels.
+  map<string, string> labels = 4;
+
+  // The current state of the Operation.
+  State state = 5;
+}
+
+// Measures the progress of a particular metric.
+message Progress {
+  // The amount of work that has been completed. Note that this may be greater
+  // than work_estimated.
+  int64 work_completed = 1;
+
+  // An estimate of how much work needs to be performed. May be zero if the
+  // work estimate is unavailable.
+  int64 work_estimated = 2;
+}
+
+// The request for
+// [google.datastore.admin.v1beta1.DatastoreAdmin.ExportEntities][google.datastore.admin.v1beta1.DatastoreAdmin.ExportEntities].
+message ExportEntitiesRequest {
+  // Project ID against which to make the request.
+  string project_id = 1;
+
+  // Client-assigned labels.
+  map<string, string> labels = 2;
+
+  // Description of what data from the project is included in the export.
+  EntityFilter entity_filter = 3;
+
+  // Location for the export metadata and data files.
+  //
+  // The full resource URL of the external storage location. Currently, only
+  // Google Cloud Storage is supported. So output_url_prefix should be of the
+  // form: `gs://BUCKET_NAME[/NAMESPACE_PATH]`, where `BUCKET_NAME` is the
+  // name of the Cloud Storage bucket and `NAMESPACE_PATH` is an optional Cloud
+  // Storage namespace path (this is not a Cloud Datastore namespace). For more
+  // information about Cloud Storage namespace paths, see
+  // [Object name
+  // considerations](https://cloud.google.com/storage/docs/naming#object-considerations).
+  //
+  // The resulting files will be nested deeper than the specified URL prefix.
+  // The final output URL will be provided in the
+  // [google.datastore.admin.v1beta1.ExportEntitiesResponse.output_url][google.datastore.admin.v1beta1.ExportEntitiesResponse.output_url]
+  // field. That value should be used for subsequent ImportEntities operations.
+  //
+  // By nesting the data files deeper, the same Cloud Storage bucket can be used
+  // in multiple ExportEntities operations without conflict.
+  string output_url_prefix = 4;
+}
+
+// The request for
+// [google.datastore.admin.v1beta1.DatastoreAdmin.ImportEntities][google.datastore.admin.v1beta1.DatastoreAdmin.ImportEntities].
+message ImportEntitiesRequest {
+  // Project ID against which to make the request.
+  string project_id = 1;
+
+  // Client-assigned labels.
+  map<string, string> labels = 2;
+
+  // The full resource URL of the external storage location. Currently, only
+  // Google Cloud Storage is supported. So input_url should be of the form:
+  // `gs://BUCKET_NAME[/NAMESPACE_PATH]/OVERALL_EXPORT_METADATA_FILE`, where
+  // `BUCKET_NAME` is the name of the Cloud Storage bucket, `NAMESPACE_PATH` is
+  // an optional Cloud Storage namespace path (this is not a Cloud Datastore
+  // namespace), and `OVERALL_EXPORT_METADATA_FILE` is the metadata file written
+  // by the ExportEntities operation. For more information about Cloud Storage
+  // namespace paths, see
+  // [Object name
+  // considerations](https://cloud.google.com/storage/docs/naming#object-considerations).
+  //
+  // For more information, see
+  // [google.datastore.admin.v1beta1.ExportEntitiesResponse.output_url][google.datastore.admin.v1beta1.ExportEntitiesResponse.output_url].
+  string input_url = 3;
+
+  // Optionally specify which kinds/namespaces are to be imported. If provided,
+  // the list must be a subset of the EntityFilter used in creating the export,
+  // otherwise a FAILED_PRECONDITION error will be returned. If no filter is
+  // specified then all entities from the export are imported.
+  EntityFilter entity_filter = 4;
+}
+
+// The response for
+// [google.datastore.admin.v1beta1.DatastoreAdmin.ExportEntities][google.datastore.admin.v1beta1.DatastoreAdmin.ExportEntities].
+message ExportEntitiesResponse {
+  // Location of the output metadata file. This can be used to begin an import
+  // into Cloud Datastore (this project or another project). See
+  // [google.datastore.admin.v1beta1.ImportEntitiesRequest.input_url][google.datastore.admin.v1beta1.ImportEntitiesRequest.input_url].
+  // Only present if the operation completed successfully.
+  string output_url = 1;
+}
+
+// Metadata for ExportEntities operations.
+message ExportEntitiesMetadata {
+  // Metadata common to all Datastore Admin operations.
+  CommonMetadata common = 1;
+
+  // An estimate of the number of entities processed.
+  Progress progress_entities = 2;
+
+  // An estimate of the number of bytes processed.
+  Progress progress_bytes = 3;
+
+  // Description of which entities are being exported.
+  EntityFilter entity_filter = 4;
+
+  // Location for the export metadata and data files. This will be the same
+  // value as the
+  // [google.datastore.admin.v1beta1.ExportEntitiesRequest.output_url_prefix][google.datastore.admin.v1beta1.ExportEntitiesRequest.output_url_prefix]
+  // field. The final output location is provided in
+  // [google.datastore.admin.v1beta1.ExportEntitiesResponse.output_url][google.datastore.admin.v1beta1.ExportEntitiesResponse.output_url].
+  string output_url_prefix = 5;
+}
+
+// Metadata for ImportEntities operations.
+message ImportEntitiesMetadata {
+  // Metadata common to all Datastore Admin operations.
+  CommonMetadata common = 1;
+
+  // An estimate of the number of entities processed.
+  Progress progress_entities = 2;
+
+  // An estimate of the number of bytes processed.
+  Progress progress_bytes = 3;
+
+  // Description of which entities are being imported.
+  EntityFilter entity_filter = 4;
+
+  // The location of the import metadata file. This will be the same value as
+  // the [google.datastore.admin.v1beta1.ExportEntitiesResponse.output_url][google.datastore.admin.v1beta1.ExportEntitiesResponse.output_url]
+  // field.
+  string input_url = 5;
+}
+
+// Identifies a subset of entities in a project. This is specified as
+// combinations of kinds and namespaces (either or both of which may be all, as
+// described in the following examples).
+// Example usage:
+//
+// Entire project:
+//   kinds=[], namespace_ids=[]
+//
+// Kinds Foo and Bar in all namespaces:
+//   kinds=['Foo', 'Bar'], namespace_ids=[]
+//
+// Kinds Foo and Bar only in the default namespace:
+//   kinds=['Foo', 'Bar'], namespace_ids=['']
+//
+// Kinds Foo and Bar in both the default and Baz namespaces:
+//   kinds=['Foo', 'Bar'], namespace_ids=['', 'Baz']
+//
+// The entire Baz namespace:
+//   kinds=[], namespace_ids=['Baz']
+message EntityFilter {
+  // If empty, then this represents all kinds.
+  repeated string kinds = 1;
+
+  // An empty list represents all namespaces. This is the preferred
+  // usage for projects that don't use namespaces.
+  //
+  // An empty string element represents the default namespace. This should be
+  // used if the project has data in non-default namespaces, but doesn't want to
+  // include them.
+  // Each namespace in this list must be unique.
+  repeated string namespace_ids = 2;
+}
+
+// Operation types.
+enum OperationType {
+  // Unspecified.
+  OPERATION_TYPE_UNSPECIFIED = 0;
+
+  // ExportEntities.
+  EXPORT_ENTITIES = 1;
+
+  // ImportEntities.
+  IMPORT_ENTITIES = 2;
+}
diff --git a/datastore/google/cloud/datastore_v1/proto/entity.proto b/datastore/google/cloud/datastore_v1/proto/entity.proto
new file mode 100644
index 000000000000..bab7953d62e2
--- /dev/null
+++ b/datastore/google/cloud/datastore_v1/proto/entity.proto
@@ -0,0 +1,204 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.datastore.v1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+import "google/type/latlng.proto";
+
+option csharp_namespace = "Google.Cloud.Datastore.V1";
+option go_package = "google.golang.org/genproto/googleapis/datastore/v1;datastore";
+option java_multiple_files = true;
+option java_outer_classname = "EntityProto";
+option java_package = "com.google.datastore.v1";
+option php_namespace = "Google\\Cloud\\Datastore\\V1";
+
+
+// A partition ID identifies a grouping of entities. The grouping is always
+// by project and namespace, however the namespace ID may be empty.
+//
+// A partition ID contains several dimensions:
+// project ID and namespace ID.
+//
+// Partition dimensions:
+//
+// - May be `""`.
+// - Must be valid UTF-8 bytes.
+// - Must have values that match regex `[A-Za-z\d\.\-_]{1,100}`
+// If the value of any dimension matches regex `__.*__`, the partition is
+// reserved/read-only.
+// A reserved/read-only partition ID is forbidden in certain documented
+// contexts.
+//
+// Foreign partition IDs (in which the project ID does
+// not match the context project ID ) are discouraged.
+// Reads and writes of foreign partition IDs may fail if the project is not in an active state.
+message PartitionId {
+  // The ID of the project to which the entities belong.
+  string project_id = 2;
+
+  // If not empty, the ID of the namespace to which the entities belong.
+  string namespace_id = 4;
+}
+
+// A unique identifier for an entity.
+// If a key's partition ID or any of its path kinds or names are
+// reserved/read-only, the key is reserved/read-only.
+// A reserved/read-only key is forbidden in certain documented contexts.
+message Key {
+  // A (kind, ID/name) pair used to construct a key path.
+  //
+  // If either name or ID is set, the element is complete.
+  // If neither is set, the element is incomplete.
+  message PathElement {
+    // The kind of the entity.
+    // A kind matching regex `__.*__` is reserved/read-only.
+    // A kind must not contain more than 1500 bytes when UTF-8 encoded.
+    // Cannot be `""`.
+    string kind = 1;
+
+    // The type of ID.
+    oneof id_type {
+      // The auto-allocated ID of the entity.
+      // Never equal to zero. Values less than zero are discouraged and may not
+      // be supported in the future.
+      int64 id = 2;
+
+      // The name of the entity.
+      // A name matching regex `__.*__` is reserved/read-only.
+      // A name must not be more than 1500 bytes when UTF-8 encoded.
+      // Cannot be `""`.
+      string name = 3;
+    }
+  }
+
+  // Entities are partitioned into subsets, currently identified by a project
+  // ID and namespace ID.
+  // Queries are scoped to a single partition.
+  PartitionId partition_id = 1;
+
+  // The entity path.
+  // An entity path consists of one or more elements composed of a kind and a
+  // string or numerical identifier, which identify entities. The first
+  // element identifies a _root entity_, the second element identifies
+  // a _child_ of the root entity, the third element identifies a child of the
+  // second entity, and so forth. The entities identified by all prefixes of
+  // the path are called the element's _ancestors_.
+  //
+  // An entity path is always fully complete: *all* of the entity's ancestors
+  // are required to be in the path along with the entity identifier itself.
+  // The only exception is that in some documented cases, the identifier in the
+  // last path element (for the entity) itself may be omitted. For example,
+  // the last path element of the key of `Mutation.insert` may have no
+  // identifier.
+  //
+  // A path can never be empty, and a path can have at most 100 elements.
+  repeated PathElement path = 2;
+}
+
+// An array value.
+message ArrayValue {
+  // Values in the array.
+  // The order of this array may not be preserved if it contains a mix of
+  // indexed and unindexed values.
+  repeated Value values = 1;
+}
+
+// A message that can hold any of the supported value types and associated
+// metadata.
+message Value {
+  // Must have a value set.
+  oneof value_type {
+    // A null value.
+    google.protobuf.NullValue null_value = 11;
+
+    // A boolean value.
+    bool boolean_value = 1;
+
+    // An integer value.
+    int64 integer_value = 2;
+
+    // A double value.
+    double double_value = 3;
+
+    // A timestamp value.
+    // When stored in the Datastore, precise only to microseconds;
+    // any additional precision is rounded down.
+    google.protobuf.Timestamp timestamp_value = 10;
+
+    // A key value.
+    Key key_value = 5;
+
+    // A UTF-8 encoded string value.
+    // When `exclude_from_indexes` is false (it is indexed) , may have at most 1500 bytes.
+    // Otherwise, may be set to at least 1,000,000 bytes.
+    string string_value = 17;
+
+    // A blob value.
+    // May have at most 1,000,000 bytes.
+    // When `exclude_from_indexes` is false, may have at most 1500 bytes.
+    // In JSON requests, must be base64-encoded.
+    bytes blob_value = 18;
+
+    // A geo point value representing a point on the surface of Earth.
+    google.type.LatLng geo_point_value = 8;
+
+    // An entity value.
+    //
+    // - May have no key.
+    // - May have a key with an incomplete key path.
+    // - May have a reserved/read-only key.
+    Entity entity_value = 6;
+
+    // An array value.
+    // Cannot contain another array value.
+    // A `Value` instance that sets field `array_value` must not set fields
+    // `meaning` or `exclude_from_indexes`.
+    ArrayValue array_value = 9;
+  }
+
+  // The `meaning` field should only be populated for backwards compatibility.
+  int32 meaning = 14;
+
+  // If the value should be excluded from all indexes including those defined
+  // explicitly.
+  bool exclude_from_indexes = 19;
+}
+
+// A Datastore data object.
+//
+// An entity is limited to 1 megabyte when stored. That _roughly_
+// corresponds to a limit of 1 megabyte for the serialized form of this
+// message.
+message Entity {
+  // The entity's key.
+  //
+  // An entity must have a key, unless otherwise documented (for example,
+  // an entity in `Value.entity_value` may have no key).
+  // An entity's kind is its key path's last element's kind,
+  // or null if it has no key.
+  Key key = 1;
+
+  // The entity's properties.
+  // The map's keys are property names.
+  // A property name matching regex `__.*__` is reserved.
+  // A reserved property name is forbidden in certain documented contexts.
+  // The name must not contain more than 500 characters.
+  // The name cannot be `""`.
+  map<string, Value> properties = 3;
+}
diff --git a/datastore/google/cloud/datastore_v1/proto/index.proto b/datastore/google/cloud/datastore_v1/proto/index.proto
new file mode 100644
index 000000000000..15013d557ea2
--- /dev/null
+++ b/datastore/google/cloud/datastore_v1/proto/index.proto
@@ -0,0 +1,122 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.datastore.admin.v1;
+
+import "google/api/annotations.proto";
+
+option csharp_namespace = "Google.Cloud.Datastore.Admin.V1";
+option go_package = "google.golang.org/genproto/googleapis/datastore/admin/v1;admin";
+option java_multiple_files = true;
+option java_outer_classname = "IndexProto";
+option java_package = "com.google.datastore.admin.v1";
+
+// A minimal index definition.
+// Next tag: 8
+message Index {
+  // Next tag: 3
+  message IndexedProperty {
+    // The property name to index.
+    // Required.
+    string name = 1;
+
+    // The indexed property's direction.  Must not be DIRECTION_UNSPECIFIED.
+    // Required.
+    Direction direction = 2;
+  }
+
+  // For an ordered index, specifies whether each of the entity's ancestors
+  // will be included.
+  enum AncestorMode {
+    // The ancestor mode is unspecified.
+    ANCESTOR_MODE_UNSPECIFIED = 0;
+
+    // Do not include the entity's ancestors in the index.
+    NONE = 1;
+
+    // Include all the entity's ancestors in the index.
+    ALL_ANCESTORS = 2;
+  }
+
+  // The direction determines how a property is indexed.
+  enum Direction {
+    // The direction is unspecified.
+    DIRECTION_UNSPECIFIED = 0;
+
+    // The property's values are indexed so as to support sequencing in
+    // ascending order and also query by <, >, <=, >=, and =.
+    ASCENDING = 1;
+
+    // The property's values are indexed so as to support sequencing in
+    // descending order and also query by <, >, <=, >=, and =.
+    DESCENDING = 2;
+  }
+
+  // The possible set of states of an index.
+  enum State {
+    // The state is unspecified.
+    STATE_UNSPECIFIED = 0;
+
+    // The index is being created, and cannot be used by queries.
+    // There is an active long-running operation for the index.
+    // The index is updated when writing an entity.
+    // Some index data may exist.
+    CREATING = 1;
+
+    // The index is ready to be used.
+    // The index is updated when writing an entity.
+    // The index is fully populated from all stored entities it applies to.
+    READY = 2;
+
+    // The index is being deleted, and cannot be used by queries.
+    // There is an active long-running operation for the index.
+    // The index is not updated when writing an entity.
+    // Some index data may exist.
+    DELETING = 3;
+
+    // The index was being created or deleted, but something went wrong.
+    // The index cannot by used by queries.
+    // There is no active long-running operation for the index,
+    // and the most recently finished long-running operation failed.
+    // The index is not updated when writing an entity.
+    // Some index data may exist.
+    ERROR = 4;
+  }
+
+  // Project ID.
+  // Output only.
+  string project_id = 1;
+
+  // The resource ID of the index.
+  // Output only.
+  string index_id = 3;
+
+  // The entity kind to which this index applies.
+  // Required.
+  string kind = 4;
+
+  // The index's ancestor mode.  Must not be ANCESTOR_MODE_UNSPECIFIED.
+  // Required.
+  AncestorMode ancestor = 5;
+
+  // An ordered sequence of property names and their index attributes.
+  // Required.
+  repeated IndexedProperty properties = 6;
+
+  // The state of the index.
+  // Output only.
+  State state = 7;
+}
diff --git a/datastore/google/cloud/datastore_v1/proto/query.proto b/datastore/google/cloud/datastore_v1/proto/query.proto
new file mode 100644
index 000000000000..2efed915a74e
--- /dev/null
+++ b/datastore/google/cloud/datastore_v1/proto/query.proto
@@ -0,0 +1,310 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.datastore.v1;
+
+import "google/api/annotations.proto";
+import "google/datastore/v1/entity.proto";
+import "google/protobuf/wrappers.proto";
+import "google/type/latlng.proto";
+
+option csharp_namespace = "Google.Cloud.Datastore.V1";
+option go_package = "google.golang.org/genproto/googleapis/datastore/v1;datastore";
+option java_multiple_files = true;
+option java_outer_classname = "QueryProto";
+option java_package = "com.google.datastore.v1";
+option php_namespace = "Google\\Cloud\\Datastore\\V1";
+
+
+// The result of fetching an entity from Datastore.
+message EntityResult {
+  // Specifies what data the 'entity' field contains.
+  // A `ResultType` is either implied (for example, in `LookupResponse.missing`
+  // from `datastore.proto`, it is always `KEY_ONLY`) or specified by context
+  // (for example, in message `QueryResultBatch`, field `entity_result_type`
+  // specifies a `ResultType` for all the values in field `entity_results`).
+  enum ResultType {
+    // Unspecified. This value is never used.
+    RESULT_TYPE_UNSPECIFIED = 0;
+
+    // The key and properties.
+    FULL = 1;
+
+    // A projected subset of properties. The entity may have no key.
+    PROJECTION = 2;
+
+    // Only the key.
+    KEY_ONLY = 3;
+  }
+
+  // The resulting entity.
+  Entity entity = 1;
+
+  // The version of the entity, a strictly positive number that monotonically
+  // increases with changes to the entity.
+  //
+  // This field is set for [`FULL`][google.datastore.v1.EntityResult.ResultType.FULL] entity
+  // results.
+  //
+  // For [missing][google.datastore.v1.LookupResponse.missing] entities in `LookupResponse`, this
+  // is the version of the snapshot that was used to look up the entity, and it
+  // is always set except for eventually consistent reads.
+  int64 version = 4;
+
+  // A cursor that points to the position after the result entity.
+  // Set only when the `EntityResult` is part of a `QueryResultBatch` message.
+  bytes cursor = 3;
+}
+
+// A query for entities.
+message Query {
+  // The projection to return. Defaults to returning all properties.
+  repeated Projection projection = 2;
+
+  // The kinds to query (if empty, returns entities of all kinds).
+  // Currently at most 1 kind may be specified.
+  repeated KindExpression kind = 3;
+
+  // The filter to apply.
+  Filter filter = 4;
+
+  // The order to apply to the query results (if empty, order is unspecified).
+  repeated PropertyOrder order = 5;
+
+  // The properties to make distinct. The query results will contain the first
+  // result for each distinct combination of values for the given properties
+  // (if empty, all results are returned).
+  repeated PropertyReference distinct_on = 6;
+
+  // A starting point for the query results. Query cursors are
+  // returned in query result batches and
+  // [can only be used to continue the same query](https://cloud.google.com/datastore/docs/concepts/queries#cursors_limits_and_offsets).
+  bytes start_cursor = 7;
+
+  // An ending point for the query results. Query cursors are
+  // returned in query result batches and
+  // [can only be used to limit the same query](https://cloud.google.com/datastore/docs/concepts/queries#cursors_limits_and_offsets).
+  bytes end_cursor = 8;
+
+  // The number of results to skip. Applies before limit, but after all other
+  // constraints. Optional. Must be >= 0 if specified.
+  int32 offset = 10;
+
+  // The maximum number of results to return. Applies after all other
+  // constraints. Optional.
+  // Unspecified is interpreted as no limit.
+  // Must be >= 0 if specified.
+  google.protobuf.Int32Value limit = 12;
+}
+
+// A representation of a kind.
+message KindExpression {
+  // The name of the kind.
+  string name = 1;
+}
+
+// A reference to a property relative to the kind expressions.
+message PropertyReference {
+  // The name of the property.
+  // If name includes "."s, it may be interpreted as a property name path.
+  string name = 2;
+}
+
+// A representation of a property in a projection.
+message Projection {
+  // The property to project.
+  PropertyReference property = 1;
+}
+
+// The desired order for a specific property.
+message PropertyOrder {
+  // The sort direction.
+  enum Direction {
+    // Unspecified. This value must not be used.
+    DIRECTION_UNSPECIFIED = 0;
+
+    // Ascending.
+    ASCENDING = 1;
+
+    // Descending.
+    DESCENDING = 2;
+  }
+
+  // The property to order by.
+  PropertyReference property = 1;
+
+  // The direction to order by. Defaults to `ASCENDING`.
+  Direction direction = 2;
+}
+
+// A holder for any type of filter.
+message Filter {
+  // The type of filter.
+  oneof filter_type {
+    // A composite filter.
+    CompositeFilter composite_filter = 1;
+
+    // A filter on a property.
+    PropertyFilter property_filter = 2;
+  }
+}
+
+// A filter that merges multiple other filters using the given operator.
+message CompositeFilter {
+  // A composite filter operator.
+  enum Operator {
+    // Unspecified. This value must not be used.
+    OPERATOR_UNSPECIFIED = 0;
+
+    // The results are required to satisfy each of the combined filters.
+    AND = 1;
+  }
+
+  // The operator for combining multiple filters.
+  Operator op = 1;
+
+  // The list of filters to combine.
+  // Must contain at least one filter.
+  repeated Filter filters = 2;
+}
+
+// A filter on a specific property.
+message PropertyFilter {
+  // A property filter operator.
+  enum Operator {
+    // Unspecified. This value must not be used.
+    OPERATOR_UNSPECIFIED = 0;
+
+    // Less than.
+    LESS_THAN = 1;
+
+    // Less than or equal.
+    LESS_THAN_OR_EQUAL = 2;
+
+    // Greater than.
+    GREATER_THAN = 3;
+
+    // Greater than or equal.
+    GREATER_THAN_OR_EQUAL = 4;
+
+    // Equal.
+    EQUAL = 5;
+
+    // Has ancestor.
+    HAS_ANCESTOR = 11;
+  }
+
+  // The property to filter by.
+  PropertyReference property = 1;
+
+  // The operator to filter by.
+  Operator op = 2;
+
+  // The value to compare the property to.
+  Value value = 3;
+}
+
+// A [GQL query](https://cloud.google.com/datastore/docs/apis/gql/gql_reference).
+message GqlQuery {
+  // A string of the format described
+  // [here](https://cloud.google.com/datastore/docs/apis/gql/gql_reference).
+  string query_string = 1;
+
+  // When false, the query string must not contain any literals and instead must
+  // bind all values. For example,
+  // `SELECT * FROM Kind WHERE a = 'string literal'` is not allowed, while
+  // `SELECT * FROM Kind WHERE a = @value` is.
+  bool allow_literals = 2;
+
+  // For each non-reserved named binding site in the query string, there must be
+  // a named parameter with that name, but not necessarily the inverse.
+  //
+  // Key must match regex `[A-Za-z_$][A-Za-z_$0-9]*`, must not match regex
+  // `__.*__`, and must not be `""`.
+  map<string, GqlQueryParameter> named_bindings = 5;
+
+  // Numbered binding site @1 references the first numbered parameter,
+  // effectively using 1-based indexing, rather than the usual 0.
+  //
+  // For each binding site numbered i in `query_string`, there must be an i-th
+  // numbered parameter. The inverse must also be true.
+  repeated GqlQueryParameter positional_bindings = 4;
+}
+
+// A binding parameter for a GQL query.
+message GqlQueryParameter {
+  // The type of parameter.
+  oneof parameter_type {
+    // A value parameter.
+    Value value = 2;
+
+    // A query cursor. Query cursors are returned in query
+    // result batches.
+    bytes cursor = 3;
+  }
+}
+
+// A batch of results produced by a query.
+message QueryResultBatch {
+  // The possible values for the `more_results` field.
+  enum MoreResultsType {
+    // Unspecified. This value is never used.
+    MORE_RESULTS_TYPE_UNSPECIFIED = 0;
+
+    // There may be additional batches to fetch from this query.
+    NOT_FINISHED = 1;
+
+    // The query is finished, but there may be more results after the limit.
+    MORE_RESULTS_AFTER_LIMIT = 2;
+
+    // The query is finished, but there may be more results after the end
+    // cursor.
+    MORE_RESULTS_AFTER_CURSOR = 4;
+
+    // The query is finished, and there are no more results.
+    NO_MORE_RESULTS = 3;
+  }
+
+  // The number of results skipped, typically because of an offset.
+  int32 skipped_results = 6;
+
+  // A cursor that points to the position after the last skipped result.
+  // Will be set when `skipped_results` != 0.
+  bytes skipped_cursor = 3;
+
+  // The result type for every entity in `entity_results`.
+  EntityResult.ResultType entity_result_type = 1;
+
+  // The results for this batch.
+  repeated EntityResult entity_results = 2;
+
+  // A cursor that points to the position after the last result in the batch.
+  bytes end_cursor = 4;
+
+  // The state of the query after the current batch.
+  MoreResultsType more_results = 5;
+
+  // The version number of the snapshot this batch was returned from.
+  // This applies to the range of results from the query's `start_cursor` (or
+  // the beginning of the query if no cursor was given) to this batch's
+  // `end_cursor` (not the query's `end_cursor`).
+  //
+  // In a single transaction, subsequent query result batches for the same query
+  // can have a greater snapshot version number. Each batch's snapshot version
+  // is valid for all preceding batches.
+  // The value will be zero for eventually consistent queries.
+  int64 snapshot_version = 7;
+}
diff --git a/datastore/synth.metadata b/datastore/synth.metadata
index c48ec8257292..4501f8f0fdb6 100644
--- a/datastore/synth.metadata
+++ b/datastore/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:16:51.374459Z",
+  "updateTime": "2019-01-23T22:54:56.744429Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/datastore/synth.py b/datastore/synth.py
index cd9c11e2bc3d..0d477f5f179d 100644
--- a/datastore/synth.py
+++ b/datastore/synth.py
@@ -27,6 +27,7 @@
     "v1",
     config_path="/google/datastore/artman_datastore.yaml",
     artman_output_name="datastore-v1",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/datastore_v1/proto")
diff --git a/dlp/synth.py b/dlp/synth.py
index b7c346390ea0..1a250d614a82 100644
--- a/dlp/synth.py
+++ b/dlp/synth.py
@@ -27,7 +27,10 @@
 # Generate dlp GAPIC layer
 # ----------------------------------------------------------------------------
 library = gapic.py_library(
-    "dlp", "v2", config_path="/google/privacy/dlp/artman_dlp_v2.yaml"
+    "dlp",
+    "v2",
+    config_path="/google/privacy/dlp/artman_dlp_v2.yaml",
+    include_protos=True,
 )
 
 excludes = ["README.rst", "nox.py", "setup.py", "docs/index.rst"]
@@ -47,8 +50,8 @@
 s.replace(
     "google/cloud/dlp_v2/proto/storage_pb2.py",
     "number regex.*\n(\s+)latex:.*\n",
-    "number regex \"(\\d\{3\}) \\d\{3\}-\\d\{4\} \"\\\n"
-    "\g<1>could be adjusted upwards if the area code is \\\n"
+    'number regex "(\\d\{3\}) \\d\{3\}-\\d\{4\} "\\\n'
+    "\g<1>could be adjusted upwards if the area code is \\\n",
 )
 
 # Fix Docstrings in google/cloud/dlp_v2/proto/storage_pb2.py
diff --git a/error_reporting/google/cloud/errorreporting_v1beta1/proto/common.proto b/error_reporting/google/cloud/errorreporting_v1beta1/proto/common.proto
new file mode 100644
index 000000000000..5d60cb2fb575
--- /dev/null
+++ b/error_reporting/google/cloud/errorreporting_v1beta1/proto/common.proto
@@ -0,0 +1,165 @@
+// Copyright 2016 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.devtools.clouderrorreporting.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/api/monitored_resource.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.ErrorReporting.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting";
+option java_multiple_files = true;
+option java_outer_classname = "CommonProto";
+option java_package = "com.google.devtools.clouderrorreporting.v1beta1";
+option php_namespace = "Google\\Cloud\\ErrorReporting\\V1beta1";
+
+
+// Description of a group of similar error events.
+message ErrorGroup {
+  // The group resource name.
+  // Example: <code>projects/my-project-123/groups/my-groupid</code>
+  string name = 1;
+
+  // Group IDs are unique for a given project. If the same kind of error
+  // occurs in different service contexts, it will receive the same group ID.
+  string group_id = 2;
+
+  // Associated tracking issues.
+  repeated TrackingIssue tracking_issues = 3;
+}
+
+// Information related to tracking the progress on resolving the error.
+message TrackingIssue {
+  // A URL pointing to a related entry in an issue tracking system.
+  // Example: https://github.com/user/project/issues/4
+  string url = 1;
+}
+
+// An error event which is returned by the Error Reporting system.
+message ErrorEvent {
+  // Time when the event occurred as provided in the error report.
+  // If the report did not contain a timestamp, the time the error was received
+  // by the Error Reporting system is used.
+  google.protobuf.Timestamp event_time = 1;
+
+  // The `ServiceContext` for which this error was reported.
+  ServiceContext service_context = 2;
+
+  // The stack trace that was reported or logged by the service.
+  string message = 3;
+
+  // Data about the context in which the error occurred.
+  ErrorContext context = 5;
+}
+
+// Describes a running service that sends errors.
+// Its version changes over time and multiple versions can run in parallel.
+message ServiceContext {
+  // An identifier of the service, such as the name of the
+  // executable, job, or Google App Engine service name. This field is expected
+  // to have a low number of values that are relatively stable over time, as
+  // opposed to `version`, which can be changed whenever new code is deployed.
+  //
+  // Contains the service name for error reports extracted from Google
+  // App Engine logs or `default` if the App Engine default service is used.
+  string service = 2;
+
+  // Represents the source code version that the developer provided,
+  // which could represent a version label or a Git SHA-1 hash, for example.
+  string version = 3;
+
+  // Type of the MonitoredResource. List of possible values:
+  // https://cloud.google.com/monitoring/api/resources
+  //
+  // Value is set automatically for incoming errors and must not be set when
+  // reporting errors.
+  string resource_type = 4;
+}
+
+// A description of the context in which an error occurred.
+// This data should be provided by the application when reporting an error,
+// unless the
+// error report has been generated automatically from Google App Engine logs.
+message ErrorContext {
+  // The HTTP request which was processed when the error was
+  // triggered.
+  HttpRequestContext http_request = 1;
+
+  // The user who caused or was affected by the crash.
+  // This can be a user ID, an email address, or an arbitrary token that
+  // uniquely identifies the user.
+  // When sending an error report, leave this field empty if the user was not
+  // logged in. In this case the
+  // Error Reporting system will use other data, such as remote IP address, to
+  // distinguish affected users. See `affected_users_count` in
+  // `ErrorGroupStats`.
+  string user = 2;
+
+  // The location in the source code where the decision was made to
+  // report the error, usually the place where it was logged.
+  // For a logged exception this would be the source line where the
+  // exception is logged, usually close to the place where it was
+  // caught. This value is in contrast to `Exception.cause_location`,
+  // which describes the source line where the exception was thrown.
+  SourceLocation report_location = 3;
+}
+
+// HTTP request data that is related to a reported error.
+// This data should be provided by the application when reporting an error,
+// unless the
+// error report has been generated automatically from Google App Engine logs.
+message HttpRequestContext {
+  // The type of HTTP request, such as `GET`, `POST`, etc.
+  string method = 1;
+
+  // The URL of the request.
+  string url = 2;
+
+  // The user agent information that is provided with the request.
+  string user_agent = 3;
+
+  // The referrer information that is provided with the request.
+  string referrer = 4;
+
+  // The HTTP response status code for the request.
+  int32 response_status_code = 5;
+
+  // The IP address from which the request originated.
+  // This can be IPv4, IPv6, or a token which is derived from the
+  // IP address, depending on the data that has been provided
+  // in the error report.
+  string remote_ip = 6;
+}
+
+// Indicates a location in the source code of the service for which
+// errors are reported.
+// This data should be provided by the application when reporting an error,
+// unless the error report has been generated automatically from Google App
+// Engine logs. All fields are optional.
+message SourceLocation {
+  // The source code filename, which can include a truncated relative
+  // path, or a full path from a production machine.
+  string file_path = 1;
+
+  // 1-based. 0 indicates that the line number is unknown.
+  int32 line_number = 2;
+
+  // Human-readable name of a function or method.
+  // The value can include optional context like the class or package name.
+  // For example, `my.package.MyClass.method` in case of Java.
+  string function_name = 4;
+}
diff --git a/error_reporting/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto b/error_reporting/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto
new file mode 100644
index 000000000000..5c32e068d98a
--- /dev/null
+++ b/error_reporting/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto
@@ -0,0 +1,61 @@
+// Copyright 2016 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.devtools.clouderrorreporting.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/devtools/clouderrorreporting/v1beta1/common.proto";
+
+option csharp_namespace = "Google.Cloud.ErrorReporting.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting";
+option java_multiple_files = true;
+option java_outer_classname = "ErrorGroupServiceProto";
+option java_package = "com.google.devtools.clouderrorreporting.v1beta1";
+option php_namespace = "Google\\Cloud\\ErrorReporting\\V1beta1";
+
+
+// Service for retrieving and updating individual error groups.
+service ErrorGroupService {
+  // Get the specified group.
+  rpc GetGroup(GetGroupRequest) returns (ErrorGroup) {
+    option (google.api.http) = { get: "/v1beta1/{group_name=projects/*/groups/*}" };
+  }
+
+  // Replace the data for the specified group.
+  // Fails if the group does not exist.
+  rpc UpdateGroup(UpdateGroupRequest) returns (ErrorGroup) {
+    option (google.api.http) = { put: "/v1beta1/{group.name=projects/*/groups/*}" body: "group" };
+  }
+}
+
+// A request to return an individual group.
+message GetGroupRequest {
+  // [Required] The group resource name. Written as
+  // <code>projects/<var>projectID</var>/groups/<var>group_name</var></code>.
+  // Call
+  // <a href="/error-reporting/reference/rest/v1beta1/projects.groupStats/list">
+  // <code>groupStats.list</code></a> to return a list of groups belonging to
+  // this project.
+  //
+  // Example: <code>projects/my-project-123/groups/my-group</code>
+  string group_name = 1;
+}
+
+// A request to replace the existing data for the given group.
+message UpdateGroupRequest {
+  // [Required] The group which replaces the resource on the server.
+  ErrorGroup group = 1;
+}
diff --git a/error_reporting/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto b/error_reporting/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto
new file mode 100644
index 000000000000..5b6213436d8e
--- /dev/null
+++ b/error_reporting/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto
@@ -0,0 +1,342 @@
+// Copyright 2016 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.devtools.clouderrorreporting.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/devtools/clouderrorreporting/v1beta1/common.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.ErrorReporting.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting";
+option java_multiple_files = true;
+option java_outer_classname = "ErrorStatsServiceProto";
+option java_package = "com.google.devtools.clouderrorreporting.v1beta1";
+option php_namespace = "Google\\Cloud\\ErrorReporting\\V1beta1";
+
+
+// An API for retrieving and managing error statistics as well as data for
+// individual events.
+service ErrorStatsService {
+  // Lists the specified groups.
+  rpc ListGroupStats(ListGroupStatsRequest) returns (ListGroupStatsResponse) {
+    option (google.api.http) = { get: "/v1beta1/{project_name=projects/*}/groupStats" };
+  }
+
+  // Lists the specified events.
+  rpc ListEvents(ListEventsRequest) returns (ListEventsResponse) {
+    option (google.api.http) = { get: "/v1beta1/{project_name=projects/*}/events" };
+  }
+
+  // Deletes all error events of a given project.
+  rpc DeleteEvents(DeleteEventsRequest) returns (DeleteEventsResponse) {
+    option (google.api.http) = { delete: "/v1beta1/{project_name=projects/*}/events" };
+  }
+}
+
+// Specifies a set of `ErrorGroupStats` to return.
+message ListGroupStatsRequest {
+  // [Required] The resource name of the Google Cloud Platform project. Written
+  // as <code>projects/</code> plus the
+  // <a href="https://support.google.com/cloud/answer/6158840">Google Cloud
+  // Platform project ID</a>.
+  //
+  // Example: <code>projects/my-project-123</code>.
+  string project_name = 1;
+
+  // [Optional] List all <code>ErrorGroupStats</code> with these IDs.
+  repeated string group_id = 2;
+
+  // [Optional] List only <code>ErrorGroupStats</code> which belong to a service
+  // context that matches the filter.
+  // Data for all service contexts is returned if this field is not specified.
+  ServiceContextFilter service_filter = 3;
+
+  // [Optional] List data for the given time range.
+  // If not set a default time range is used. The field time_range_begin
+  // in the response will specify the beginning of this time range.
+  // Only <code>ErrorGroupStats</code> with a non-zero count in the given time
+  // range are returned, unless the request contains an explicit group_id list.
+  // If a group_id list is given, also <code>ErrorGroupStats</code> with zero
+  // occurrences are returned.
+  QueryTimeRange time_range = 5;
+
+  // [Optional] The preferred duration for a single returned `TimedCount`.
+  // If not set, no timed counts are returned.
+  google.protobuf.Duration timed_count_duration = 6;
+
+  // [Optional] The alignment of the timed counts to be returned.
+  // Default is `ALIGNMENT_EQUAL_AT_END`.
+  TimedCountAlignment alignment = 7;
+
+  // [Optional] Time where the timed counts shall be aligned if rounded
+  // alignment is chosen. Default is 00:00 UTC.
+  google.protobuf.Timestamp alignment_time = 8;
+
+  // [Optional] The sort order in which the results are returned.
+  // Default is `COUNT_DESC`.
+  ErrorGroupOrder order = 9;
+
+  // [Optional] The maximum number of results to return per response.
+  // Default is 20.
+  int32 page_size = 11;
+
+  // [Optional] A `next_page_token` provided by a previous response. To view
+  // additional results, pass this token along with the identical query
+  // parameters as the first request.
+  string page_token = 12;
+}
+
+// Contains a set of requested error group stats.
+message ListGroupStatsResponse {
+  // The error group stats which match the given request.
+  repeated ErrorGroupStats error_group_stats = 1;
+
+  // If non-empty, more results are available.
+  // Pass this token, along with the same query parameters as the first
+  // request, to view the next page of results.
+  string next_page_token = 2;
+
+  // The timestamp specifies the start time to which the request was restricted.
+  // The start time is set based on the requested time range. It may be adjusted
+  // to a later time if a project has exceeded the storage quota and older data
+  // has been deleted.
+  google.protobuf.Timestamp time_range_begin = 4;
+}
+
+// Data extracted for a specific group based on certain filter criteria,
+// such as a given time period and/or service filter.
+message ErrorGroupStats {
+  // Group data that is independent of the filter criteria.
+  ErrorGroup group = 1;
+
+  // Approximate total number of events in the given group that match
+  // the filter criteria.
+  int64 count = 2;
+
+  // Approximate number of affected users in the given group that
+  // match the filter criteria.
+  // Users are distinguished by data in the `ErrorContext` of the
+  // individual error events, such as their login name or their remote
+  // IP address in case of HTTP requests.
+  // The number of affected users can be zero even if the number of
+  // errors is non-zero if no data was provided from which the
+  // affected user could be deduced.
+  // Users are counted based on data in the request
+  // context that was provided in the error report. If more users are
+  // implicitly affected, such as due to a crash of the whole service,
+  // this is not reflected here.
+  int64 affected_users_count = 3;
+
+  // Approximate number of occurrences over time.
+  // Timed counts returned by ListGroups are guaranteed to be:
+  //
+  // - Inside the requested time interval
+  // - Non-overlapping, and
+  // - Ordered by ascending time.
+  repeated TimedCount timed_counts = 4;
+
+  // Approximate first occurrence that was ever seen for this group
+  // and which matches the given filter criteria, ignoring the
+  // time_range that was specified in the request.
+  google.protobuf.Timestamp first_seen_time = 5;
+
+  // Approximate last occurrence that was ever seen for this group and
+  // which matches the given filter criteria, ignoring the time_range
+  // that was specified in the request.
+  google.protobuf.Timestamp last_seen_time = 6;
+
+  // Service contexts with a non-zero error count for the given filter
+  // criteria. This list can be truncated if multiple services are affected.
+  // Refer to `num_affected_services` for the total count.
+  repeated ServiceContext affected_services = 7;
+
+  // The total number of services with a non-zero error count for the given
+  // filter criteria.
+  int32 num_affected_services = 8;
+
+  // An arbitrary event that is chosen as representative for the whole group.
+  // The representative event is intended to be used as a quick preview for
+  // the whole group. Events in the group are usually sufficiently similar
+  // to each other such that showing an arbitrary representative provides
+  // insight into the characteristics of the group as a whole.
+  ErrorEvent representative = 9;
+}
+
+// The number of errors in a given time period.
+// All numbers are approximate since the error events are sampled
+// before counting them.
+message TimedCount {
+  // Approximate number of occurrences in the given time period.
+  int64 count = 1;
+
+  // Start of the time period to which `count` refers (included).
+  google.protobuf.Timestamp start_time = 2;
+
+  // End of the time period to which `count` refers (excluded).
+  google.protobuf.Timestamp end_time = 3;
+}
+
+// Specifies a set of error events to return.
+message ListEventsRequest {
+  // [Required] The resource name of the Google Cloud Platform project. Written
+  // as `projects/` plus the
+  // [Google Cloud Platform project
+  // ID](https://support.google.com/cloud/answer/6158840).
+  // Example: `projects/my-project-123`.
+  string project_name = 1;
+
+  // [Required] The group for which events shall be returned.
+  string group_id = 2;
+
+  // [Optional] List only ErrorGroups which belong to a service context that
+  // matches the filter.
+  // Data for all service contexts is returned if this field is not specified.
+  ServiceContextFilter service_filter = 3;
+
+  // [Optional] List only data for the given time range.
+  // If not set a default time range is used. The field time_range_begin
+  // in the response will specify the beginning of this time range.
+  QueryTimeRange time_range = 4;
+
+  // [Optional] The maximum number of results to return per response.
+  int32 page_size = 6;
+
+  // [Optional] A `next_page_token` provided by a previous response.
+  string page_token = 7;
+}
+
+// Contains a set of requested error events.
+message ListEventsResponse {
+  // The error events which match the given request.
+  repeated ErrorEvent error_events = 1;
+
+  // If non-empty, more results are available.
+  // Pass this token, along with the same query parameters as the first
+  // request, to view the next page of results.
+  string next_page_token = 2;
+
+  // The timestamp specifies the start time to which the request was restricted.
+  google.protobuf.Timestamp time_range_begin = 4;
+}
+
+// Requests might be rejected or the resulting timed count durations might be
+// adjusted for lower durations.
+message QueryTimeRange {
+  // The supported time ranges.
+  enum Period {
+    // Do not use.
+    PERIOD_UNSPECIFIED = 0;
+
+    // Retrieve data for the last hour.
+    // Recommended minimum timed count duration: 1 min.
+    PERIOD_1_HOUR = 1;
+
+    // Retrieve data for the last 6 hours.
+    // Recommended minimum timed count duration: 10 min.
+    PERIOD_6_HOURS = 2;
+
+    // Retrieve data for the last day.
+    // Recommended minimum timed count duration: 1 hour.
+    PERIOD_1_DAY = 3;
+
+    // Retrieve data for the last week.
+    // Recommended minimum timed count duration: 6 hours.
+    PERIOD_1_WEEK = 4;
+
+    // Retrieve data for the last 30 days.
+    // Recommended minimum timed count duration: 1 day.
+    PERIOD_30_DAYS = 5;
+  }
+
+  // Restricts the query to the specified time range.
+  Period period = 1;
+}
+
+// Specifies criteria for filtering a subset of service contexts.
+// The fields in the filter correspond to the fields in `ServiceContext`.
+// Only exact, case-sensitive matches are supported.
+// If a field is unset or empty, it matches arbitrary values.
+message ServiceContextFilter {
+  // [Optional] The exact value to match against
+  // [`ServiceContext.service`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.service).
+  string service = 2;
+
+  // [Optional] The exact value to match against
+  // [`ServiceContext.version`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.version).
+  string version = 3;
+
+  // [Optional] The exact value to match against
+  // [`ServiceContext.resource_type`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.resource_type).
+  string resource_type = 4;
+}
+
+// Deletes all events in the project.
+message DeleteEventsRequest {
+  // [Required] The resource name of the Google Cloud Platform project. Written
+  // as `projects/` plus the
+  // [Google Cloud Platform project
+  // ID](https://support.google.com/cloud/answer/6158840).
+  // Example: `projects/my-project-123`.
+  string project_name = 1;
+}
+
+// Response message for deleting error events.
+message DeleteEventsResponse {
+
+}
+
+// Specifies how the time periods of error group counts are aligned.
+enum TimedCountAlignment {
+  // No alignment specified.
+  ERROR_COUNT_ALIGNMENT_UNSPECIFIED = 0;
+
+  // The time periods shall be consecutive, have width equal to the
+  // requested duration, and be aligned at the `alignment_time` provided in
+  // the request.
+  // The `alignment_time` does not have to be inside the query period but
+  // even if it is outside, only time periods are returned which overlap
+  // with the query period.
+  // A rounded alignment will typically result in a
+  // different size of the first or the last time period.
+  ALIGNMENT_EQUAL_ROUNDED = 1;
+
+  // The time periods shall be consecutive, have width equal to the
+  // requested duration, and be aligned at the end of the requested time
+  // period. This can result in a different size of the
+  // first time period.
+  ALIGNMENT_EQUAL_AT_END = 2;
+}
+
+// A sorting order of error groups.
+enum ErrorGroupOrder {
+  // No group order specified.
+  GROUP_ORDER_UNSPECIFIED = 0;
+
+  // Total count of errors in the given time window in descending order.
+  COUNT_DESC = 1;
+
+  // Timestamp when the group was last seen in the given time window
+  // in descending order.
+  LAST_SEEN_DESC = 2;
+
+  // Timestamp when the group was created in descending order.
+  CREATED_DESC = 3;
+
+  // Number of affected users in the given time window in descending order.
+  AFFECTED_USERS_DESC = 4;
+}
diff --git a/error_reporting/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto b/error_reporting/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto
new file mode 100644
index 000000000000..cf22f4971834
--- /dev/null
+++ b/error_reporting/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto
@@ -0,0 +1,82 @@
+// Copyright 2016 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.devtools.clouderrorreporting.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/devtools/clouderrorreporting/v1beta1/common.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.ErrorReporting.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting";
+option java_multiple_files = true;
+option java_outer_classname = "ReportErrorsServiceProto";
+option java_package = "com.google.devtools.clouderrorreporting.v1beta1";
+option php_namespace = "Google\\Cloud\\ErrorReporting\\V1beta1";
+
+
+// An API for reporting error events.
+service ReportErrorsService {
+  // Report an individual error event.
+  //
+  // This endpoint accepts <strong>either</strong> an OAuth token,
+  // <strong>or</strong> an
+  // <a href="https://support.google.com/cloud/answer/6158862">API key</a>
+  // for authentication. To use an API key, append it to the URL as the value of
+  // a `key` parameter. For example:
+  // <pre>POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456</pre>
+  rpc ReportErrorEvent(ReportErrorEventRequest) returns (ReportErrorEventResponse) {
+    option (google.api.http) = { post: "/v1beta1/{project_name=projects/*}/events:report" body: "event" };
+  }
+}
+
+// A request for reporting an individual error event.
+message ReportErrorEventRequest {
+  // [Required] The resource name of the Google Cloud Platform project. Written
+  // as `projects/` plus the
+  // [Google Cloud Platform project ID](https://support.google.com/cloud/answer/6158840).
+  // Example: `projects/my-project-123`.
+  string project_name = 1;
+
+  // [Required] The error event to be reported.
+  ReportedErrorEvent event = 2;
+}
+
+// Response for reporting an individual error event.
+// Data may be added to this message in the future.
+message ReportErrorEventResponse {
+
+}
+
+// An error event which is reported to the Error Reporting system.
+message ReportedErrorEvent {
+  // [Optional] Time when the event occurred.
+  // If not provided, the time when the event was received by the
+  // Error Reporting system will be used.
+  google.protobuf.Timestamp event_time = 1;
+
+  // [Required] The service context in which this error has occurred.
+  ServiceContext service_context = 2;
+
+  // [Required] A message describing the error. The message can contain an
+  // exception stack in one of the supported programming languages and formats.
+  // In that case, the message is parsed and detailed exception information
+  // is returned when retrieving the error event again.
+  string message = 3;
+
+  // [Optional] A description of the context in which the error occurred.
+  ErrorContext context = 4;
+}
diff --git a/error_reporting/google/cloud/errorreporting_v1beta1/proto/synth.metadata b/error_reporting/google/cloud/errorreporting_v1beta1/proto/synth.metadata
new file mode 100644
index 000000000000..aa85442f198e
--- /dev/null
+++ b/error_reporting/google/cloud/errorreporting_v1beta1/proto/synth.metadata
@@ -0,0 +1,3 @@
+{
+  "updateTime": "2019-01-23T23:03:31.526988Z"
+}
\ No newline at end of file
diff --git a/error_reporting/synth.metadata b/error_reporting/synth.metadata
index 6227a41a3012..6c0c17eca3e2 100644
--- a/error_reporting/synth.metadata
+++ b/error_reporting/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:18:30.046159Z",
+  "updateTime": "2019-01-23T23:04:41.736646Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
@@ -28,7 +28,7 @@
     {
       "client": {
         "source": "googleapis",
-        "apiName": "error_reporting",
+        "apiName": "errorreporting",
         "apiVersion": "v1beta1",
         "language": "python",
         "generator": "gapic",
diff --git a/error_reporting/synth.py b/error_reporting/synth.py
index 540761b4c55a..0dd24c997469 100644
--- a/error_reporting/synth.py
+++ b/error_reporting/synth.py
@@ -23,10 +23,11 @@
 # Generate error_reporting GAPIC layer
 # ----------------------------------------------------------------------------
 library = gapic.py_library(
-    "error_reporting",
+    "errorreporting",
     "v1beta1",
     config_path="/google/devtools/clouderrorreporting" "/artman_errorreporting.yaml",
     artman_output_name="error-reporting-v1beta1",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/errorreporting_v1beta1/proto")
diff --git a/firestore/google/cloud/firestore_v1beta1/proto/common.proto b/firestore/google/cloud/firestore_v1beta1/proto/common.proto
new file mode 100644
index 000000000000..4046a0d6743c
--- /dev/null
+++ b/firestore/google/cloud/firestore_v1beta1/proto/common.proto
@@ -0,0 +1,84 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.firestore.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Firestore.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/firestore/v1beta1;firestore";
+option java_multiple_files = true;
+option java_outer_classname = "CommonProto";
+option java_package = "com.google.firestore.v1beta1";
+option objc_class_prefix = "GCFS";
+option php_namespace = "Google\\Cloud\\Firestore\\V1beta1";
+
+
+// A set of field paths on a document.
+// Used to restrict a get or update operation on a document to a subset of its
+// fields.
+// This is different from standard field masks, as this is always scoped to a
+// [Document][google.firestore.v1beta1.Document], and takes in account the dynamic nature of [Value][google.firestore.v1beta1.Value].
+message DocumentMask {
+  // The list of field paths in the mask. See [Document.fields][google.firestore.v1beta1.Document.fields] for a field
+  // path syntax reference.
+  repeated string field_paths = 1;
+}
+
+// A precondition on a document, used for conditional operations.
+message Precondition {
+  // The type of precondition.
+  oneof condition_type {
+    // When set to `true`, the target document must exist.
+    // When set to `false`, the target document must not exist.
+    bool exists = 1;
+
+    // When set, the target document must exist and have been last updated at
+    // that time.
+    google.protobuf.Timestamp update_time = 2;
+  }
+}
+
+// Options for creating a new transaction.
+message TransactionOptions {
+  // Options for a transaction that can be used to read and write documents.
+  message ReadWrite {
+    // An optional transaction to retry.
+    bytes retry_transaction = 1;
+  }
+
+  // Options for a transaction that can only be used to read documents.
+  message ReadOnly {
+    // The consistency mode for this transaction. If not set, defaults to strong
+    // consistency.
+    oneof consistency_selector {
+      // Reads documents at the given time.
+      // This may not be older than 60 seconds.
+      google.protobuf.Timestamp read_time = 2;
+    }
+  }
+
+  // The mode of the transaction.
+  oneof mode {
+    // The transaction can only be used for read operations.
+    ReadOnly read_only = 2;
+
+    // The transaction can be used for both read and write operations.
+    ReadWrite read_write = 3;
+  }
+}
diff --git a/firestore/google/cloud/firestore_v1beta1/proto/document.proto b/firestore/google/cloud/firestore_v1beta1/proto/document.proto
new file mode 100644
index 000000000000..beb525a4eec6
--- /dev/null
+++ b/firestore/google/cloud/firestore_v1beta1/proto/document.proto
@@ -0,0 +1,151 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.firestore.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+import "google/type/latlng.proto";
+
+option csharp_namespace = "Google.Cloud.Firestore.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/firestore/v1beta1;firestore";
+option java_multiple_files = true;
+option java_outer_classname = "DocumentProto";
+option java_package = "com.google.firestore.v1beta1";
+option objc_class_prefix = "GCFS";
+option php_namespace = "Google\\Cloud\\Firestore\\V1beta1";
+
+
+// A Firestore document.
+//
+// Must not exceed 1 MiB - 4 bytes.
+message Document {
+  // The resource name of the document, for example
+  // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+  string name = 1;
+
+  // The document's fields.
+  //
+  // The map keys represent field names.
+  //
+  // A simple field name contains only characters `a` to `z`, `A` to `Z`,
+  // `0` to `9`, or `_`, and must not start with `0` to `9`. For example,
+  // `foo_bar_17`.
+  //
+  // Field names matching the regular expression `__.*__` are reserved. Reserved
+  // field names are forbidden except in certain documented contexts. The map
+  // keys, represented as UTF-8, must not exceed 1,500 bytes and cannot be
+  // empty.
+  //
+  // Field paths may be used in other contexts to refer to structured fields
+  // defined here. For `map_value`, the field path is represented by the simple
+  // or quoted field names of the containing fields, delimited by `.`. For
+  // example, the structured field
+  // `"foo" : { map_value: { "x&y" : { string_value: "hello" }}}` would be
+  // represented by the field path `foo.x&y`.
+  //
+  // Within a field path, a quoted field name starts and ends with `` ` `` and
+  // may contain any character. Some characters, including `` ` ``, must be
+  // escaped using a `\`. For example, `` `x&y` `` represents `x&y` and
+  // `` `bak\`tik` `` represents `` bak`tik ``.
+  map<string, Value> fields = 2;
+
+  // Output only. The time at which the document was created.
+  //
+  // This value increases monotonically when a document is deleted then
+  // recreated. It can also be compared to values from other documents and
+  // the `read_time` of a query.
+  google.protobuf.Timestamp create_time = 3;
+
+  // Output only. The time at which the document was last changed.
+  //
+  // This value is initially set to the `create_time` then increases
+  // monotonically with each change to the document. It can also be
+  // compared to values from other documents and the `read_time` of a query.
+  google.protobuf.Timestamp update_time = 4;
+}
+
+// A message that can hold any of the supported value types.
+message Value {
+  // Must have a value set.
+  oneof value_type {
+    // A null value.
+    google.protobuf.NullValue null_value = 11;
+
+    // A boolean value.
+    bool boolean_value = 1;
+
+    // An integer value.
+    int64 integer_value = 2;
+
+    // A double value.
+    double double_value = 3;
+
+    // A timestamp value.
+    //
+    // Precise only to microseconds. When stored, any additional precision is
+    // rounded down.
+    google.protobuf.Timestamp timestamp_value = 10;
+
+    // A string value.
+    //
+    // The string, represented as UTF-8, must not exceed 1 MiB - 89 bytes.
+    // Only the first 1,500 bytes of the UTF-8 representation are considered by
+    // queries.
+    string string_value = 17;
+
+    // A bytes value.
+    //
+    // Must not exceed 1 MiB - 89 bytes.
+    // Only the first 1,500 bytes are considered by queries.
+    bytes bytes_value = 18;
+
+    // A reference to a document. For example:
+    // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+    string reference_value = 5;
+
+    // A geo point value representing a point on the surface of Earth.
+    google.type.LatLng geo_point_value = 8;
+
+    // An array value.
+    //
+    // Cannot directly contain another array value, though can contain an
+    // map which contains another array.
+    ArrayValue array_value = 9;
+
+    // A map value.
+    MapValue map_value = 6;
+  }
+}
+
+// An array value.
+message ArrayValue {
+  // Values in the array.
+  repeated Value values = 1;
+}
+
+// A map value.
+message MapValue {
+  // The map's fields.
+  //
+  // The map keys represent field names. Field names matching the regular
+  // expression `__.*__` are reserved. Reserved field names are forbidden except
+  // in certain documented contexts. The map keys, represented as UTF-8, must
+  // not exceed 1,500 bytes and cannot be empty.
+  map<string, Value> fields = 1;
+}
diff --git a/firestore/google/cloud/firestore_v1beta1/proto/field.proto b/firestore/google/cloud/firestore_v1beta1/proto/field.proto
new file mode 100644
index 000000000000..9d1534eb1f63
--- /dev/null
+++ b/firestore/google/cloud/firestore_v1beta1/proto/field.proto
@@ -0,0 +1,95 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.firestore.admin.v1beta2;
+
+import "google/api/annotations.proto";
+import "google/firestore/admin/v1beta2/index.proto";
+
+option csharp_namespace = "Google.Cloud.Firestore.Admin.V1Beta2";
+option go_package = "google.golang.org/genproto/googleapis/firestore/admin/v1beta2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "FieldProto";
+option java_package = "com.google.firestore.admin.v1beta2";
+option objc_class_prefix = "GCFS";
+
+
+// Represents a single field in the database.
+//
+// Fields are grouped by their "Collection Group", which represent all
+// collections in the database with the same id.
+message Field {
+  // The index configuration for this field.
+  message IndexConfig {
+    // The indexes supported for this field.
+    repeated Index indexes = 1;
+
+    // Output only.
+    // When true, the `Field`'s index configuration is set from the
+    // configuration specified by the `ancestor_field`.
+    // When false, the `Field`'s index configuration is defined explicitly.
+    bool uses_ancestor_config = 2;
+
+    // Output only.
+    // Specifies the resource name of the `Field` from which this field's
+    // index configuration is set (when `uses_ancestor_config` is true),
+    // or from which it *would* be set if this field had no index configuration
+    // (when `uses_ancestor_config` is false).
+    string ancestor_field = 3;
+
+    // Output only
+    // When true, the `Field`'s index configuration is in the process of being
+    // reverted. Once complete, the index config will transition to the same
+    // state as the field specified by `ancestor_field`, at which point
+    // `uses_ancestor_config` will be `true` and `reverting` will be `false`.
+    bool reverting = 4;
+  }
+
+  // A field name of the form
+  // `projects/{project_id}/databases/{database_id}/collectionGroups/{collection_id}/fields/{field_path}`
+  //
+  // A field path may be a simple field name, e.g. `address` or a path to fields
+  // within map_value , e.g. `address.city`,
+  // or a special field path. The only valid special field is `*`, which
+  // represents any field.
+  //
+  // Field paths may be quoted using ` (backtick). The only character that needs
+  // to be escaped within a quoted field path is the backtick character itself,
+  // escaped using a backslash. Special characters in field paths that
+  // must be quoted include: `*`, `.`,
+  // ``` (backtick), `[`, `]`, as well as any ascii symbolic characters.
+  //
+  // Examples:
+  // (Note: Comments here are written in markdown syntax, so there is an
+  //  additional layer of backticks to represent a code block)
+  // `\`address.city\`` represents a field named `address.city`, not the map key
+  // `city` in the field `address`.
+  // `\`*\`` represents a field named `*`, not any field.
+  //
+  // A special `Field` contains the default indexing settings for all fields.
+  // This field's resource name is:
+  // `projects/{project_id}/databases/{database_id}/collectionGroups/__default__/fields/*`
+  // Indexes defined on this `Field` will be applied to all fields which do not
+  // have their own `Field` index configuration.
+  string name = 1;
+
+  // The index configuration for this field. If unset, field indexing will
+  // revert to the configuration defined by the `ancestor_field`. To
+  // explicitly remove all indexes for this field, specify an index config
+  // with an empty list of indexes.
+  IndexConfig index_config = 2;
+}
diff --git a/firestore/google/cloud/firestore_v1beta1/proto/firestore.proto b/firestore/google/cloud/firestore_v1beta1/proto/firestore.proto
new file mode 100644
index 000000000000..39ea90e2a7b5
--- /dev/null
+++ b/firestore/google/cloud/firestore_v1beta1/proto/firestore.proto
@@ -0,0 +1,761 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.firestore.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/firestore/v1beta1/common.proto";
+import "google/firestore/v1beta1/document.proto";
+import "google/firestore/v1beta1/query.proto";
+import "google/firestore/v1beta1/write.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.Firestore.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/firestore/v1beta1;firestore";
+option java_multiple_files = true;
+option java_outer_classname = "FirestoreProto";
+option java_package = "com.google.firestore.v1beta1";
+option objc_class_prefix = "GCFS";
+option php_namespace = "Google\\Cloud\\Firestore\\V1beta1";
+// Specification of the Firestore API.
+
+// The Cloud Firestore service.
+//
+// This service exposes several types of comparable timestamps:
+//
+// *    `create_time` - The time at which a document was created. Changes only
+//      when a document is deleted, then re-created. Increases in a strict
+//       monotonic fashion.
+// *    `update_time` - The time at which a document was last updated. Changes
+//      every time a document is modified. Does not change when a write results
+//      in no modifications. Increases in a strict monotonic fashion.
+// *    `read_time` - The time at which a particular state was observed. Used
+//      to denote a consistent snapshot of the database or the time at which a
+//      Document was observed to not exist.
+// *    `commit_time` - The time at which the writes in a transaction were
+//      committed. Any read with an equal or greater `read_time` is guaranteed
+//      to see the effects of the transaction.
+service Firestore {
+  // Gets a single document.
+  rpc GetDocument(GetDocumentRequest) returns (Document) {
+    option (google.api.http) = {
+      get: "/v1beta1/{name=projects/*/databases/*/documents/*/**}"
+    };
+  }
+
+  // Lists documents.
+  rpc ListDocuments(ListDocumentsRequest) returns (ListDocumentsResponse) {
+    option (google.api.http) = {
+      get: "/v1beta1/{parent=projects/*/databases/*/documents/*/**}/{collection_id}"
+    };
+  }
+
+  // Creates a new document.
+  rpc CreateDocument(CreateDocumentRequest) returns (Document) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=projects/*/databases/*/documents/**}/{collection_id}"
+      body: "document"
+    };
+  }
+
+  // Updates or inserts a document.
+  rpc UpdateDocument(UpdateDocumentRequest) returns (Document) {
+    option (google.api.http) = {
+      patch: "/v1beta1/{document.name=projects/*/databases/*/documents/*/**}"
+      body: "document"
+    };
+  }
+
+  // Deletes a document.
+  rpc DeleteDocument(DeleteDocumentRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1beta1/{name=projects/*/databases/*/documents/*/**}"
+    };
+  }
+
+  // Gets multiple documents.
+  //
+  // Documents returned by this method are not guaranteed to be returned in the
+  // same order that they were requested.
+  rpc BatchGetDocuments(BatchGetDocumentsRequest) returns (stream BatchGetDocumentsResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/{database=projects/*/databases/*}/documents:batchGet"
+      body: "*"
+    };
+  }
+
+  // Starts a new transaction.
+  rpc BeginTransaction(BeginTransactionRequest) returns (BeginTransactionResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/{database=projects/*/databases/*}/documents:beginTransaction"
+      body: "*"
+    };
+  }
+
+  // Commits a transaction, while optionally updating documents.
+  rpc Commit(CommitRequest) returns (CommitResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/{database=projects/*/databases/*}/documents:commit"
+      body: "*"
+    };
+  }
+
+  // Rolls back a transaction.
+  rpc Rollback(RollbackRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1beta1/{database=projects/*/databases/*}/documents:rollback"
+      body: "*"
+    };
+  }
+
+  // Runs a query.
+  rpc RunQuery(RunQueryRequest) returns (stream RunQueryResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=projects/*/databases/*/documents}:runQuery"
+      body: "*"
+      additional_bindings {
+        post: "/v1beta1/{parent=projects/*/databases/*/documents/*/**}:runQuery"
+        body: "*"
+      }
+    };
+  }
+
+  // Streams batches of document updates and deletes, in order.
+  rpc Write(stream WriteRequest) returns (stream WriteResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/{database=projects/*/databases/*}/documents:write"
+      body: "*"
+    };
+  }
+
+  // Listens to changes.
+  rpc Listen(stream ListenRequest) returns (stream ListenResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/{database=projects/*/databases/*}/documents:listen"
+      body: "*"
+    };
+  }
+
+  // Lists all the collection IDs underneath a document.
+  rpc ListCollectionIds(ListCollectionIdsRequest) returns (ListCollectionIdsResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=projects/*/databases/*/documents}:listCollectionIds"
+      body: "*"
+      additional_bindings {
+        post: "/v1beta1/{parent=projects/*/databases/*/documents/*/**}:listCollectionIds"
+        body: "*"
+      }
+    };
+  }
+}
+
+// The request for [Firestore.GetDocument][google.firestore.v1beta1.Firestore.GetDocument].
+message GetDocumentRequest {
+  // The resource name of the Document to get. In the format:
+  // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+  string name = 1;
+
+  // The fields to return. If not set, returns all fields.
+  //
+  // If the document has a field that is not present in this mask, that field
+  // will not be returned in the response.
+  DocumentMask mask = 2;
+
+  // The consistency mode for this transaction.
+  // If not set, defaults to strong consistency.
+  oneof consistency_selector {
+    // Reads the document in a transaction.
+    bytes transaction = 3;
+
+    // Reads the version of the document at the given time.
+    // This may not be older than 60 seconds.
+    google.protobuf.Timestamp read_time = 5;
+  }
+}
+
+// The request for [Firestore.ListDocuments][google.firestore.v1beta1.Firestore.ListDocuments].
+message ListDocumentsRequest {
+  // The parent resource name. In the format:
+  // `projects/{project_id}/databases/{database_id}/documents` or
+  // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+  // For example:
+  // `projects/my-project/databases/my-database/documents` or
+  // `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom`
+  string parent = 1;
+
+  // The collection ID, relative to `parent`, to list. For example: `chatrooms`
+  // or `messages`.
+  string collection_id = 2;
+
+  // The maximum number of documents to return.
+  int32 page_size = 3;
+
+  // The `next_page_token` value returned from a previous List request, if any.
+  string page_token = 4;
+
+  // The order to sort results by. For example: `priority desc, name`.
+  string order_by = 6;
+
+  // The fields to return. If not set, returns all fields.
+  //
+  // If a document has a field that is not present in this mask, that field
+  // will not be returned in the response.
+  DocumentMask mask = 7;
+
+  // The consistency mode for this transaction.
+  // If not set, defaults to strong consistency.
+  oneof consistency_selector {
+    // Reads documents in a transaction.
+    bytes transaction = 8;
+
+    // Reads documents as they were at the given time.
+    // This may not be older than 60 seconds.
+    google.protobuf.Timestamp read_time = 10;
+  }
+
+  // If the list should show missing documents. A missing document is a
+  // document that does not exist but has sub-documents. These documents will
+  // be returned with a key but will not have fields, [Document.create_time][google.firestore.v1beta1.Document.create_time],
+  // or [Document.update_time][google.firestore.v1beta1.Document.update_time] set.
+  //
+  // Requests with `show_missing` may not specify `where` or
+  // `order_by`.
+  bool show_missing = 12;
+}
+
+// The response for [Firestore.ListDocuments][google.firestore.v1beta1.Firestore.ListDocuments].
+message ListDocumentsResponse {
+  // The Documents found.
+  repeated Document documents = 1;
+
+  // The next page token.
+  string next_page_token = 2;
+}
+
+// The request for [Firestore.CreateDocument][google.firestore.v1beta1.Firestore.CreateDocument].
+message CreateDocumentRequest {
+  // The parent resource. For example:
+  // `projects/{project_id}/databases/{database_id}/documents` or
+  // `projects/{project_id}/databases/{database_id}/documents/chatrooms/{chatroom_id}`
+  string parent = 1;
+
+  // The collection ID, relative to `parent`, to list. For example: `chatrooms`.
+  string collection_id = 2;
+
+  // The client-assigned document ID to use for this document.
+  //
+  // Optional. If not specified, an ID will be assigned by the service.
+  string document_id = 3;
+
+  // The document to create. `name` must not be set.
+  Document document = 4;
+
+  // The fields to return. If not set, returns all fields.
+  //
+  // If the document has a field that is not present in this mask, that field
+  // will not be returned in the response.
+  DocumentMask mask = 5;
+}
+
+// The request for [Firestore.UpdateDocument][google.firestore.v1beta1.Firestore.UpdateDocument].
+message UpdateDocumentRequest {
+  // The updated document.
+  // Creates the document if it does not already exist.
+  Document document = 1;
+
+  // The fields to update.
+  // None of the field paths in the mask may contain a reserved name.
+  //
+  // If the document exists on the server and has fields not referenced in the
+  // mask, they are left unchanged.
+  // Fields referenced in the mask, but not present in the input document, are
+  // deleted from the document on the server.
+  DocumentMask update_mask = 2;
+
+  // The fields to return. If not set, returns all fields.
+  //
+  // If the document has a field that is not present in this mask, that field
+  // will not be returned in the response.
+  DocumentMask mask = 3;
+
+  // An optional precondition on the document.
+  // The request will fail if this is set and not met by the target document.
+  Precondition current_document = 4;
+}
+
+// The request for [Firestore.DeleteDocument][google.firestore.v1beta1.Firestore.DeleteDocument].
+message DeleteDocumentRequest {
+  // The resource name of the Document to delete. In the format:
+  // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+  string name = 1;
+
+  // An optional precondition on the document.
+  // The request will fail if this is set and not met by the target document.
+  Precondition current_document = 2;
+}
+
+// The request for [Firestore.BatchGetDocuments][google.firestore.v1beta1.Firestore.BatchGetDocuments].
+message BatchGetDocumentsRequest {
+  // The database name. In the format:
+  // `projects/{project_id}/databases/{database_id}`.
+  string database = 1;
+
+  // The names of the documents to retrieve. In the format:
+  // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+  // The request will fail if any of the document is not a child resource of the
+  // given `database`. Duplicate names will be elided.
+  repeated string documents = 2;
+
+  // The fields to return. If not set, returns all fields.
+  //
+  // If a document has a field that is not present in this mask, that field will
+  // not be returned in the response.
+  DocumentMask mask = 3;
+
+  // The consistency mode for this transaction.
+  // If not set, defaults to strong consistency.
+  oneof consistency_selector {
+    // Reads documents in a transaction.
+    bytes transaction = 4;
+
+    // Starts a new transaction and reads the documents.
+    // Defaults to a read-only transaction.
+    // The new transaction ID will be returned as the first response in the
+    // stream.
+    TransactionOptions new_transaction = 5;
+
+    // Reads documents as they were at the given time.
+    // This may not be older than 60 seconds.
+    google.protobuf.Timestamp read_time = 7;
+  }
+}
+
+// The streamed response for [Firestore.BatchGetDocuments][google.firestore.v1beta1.Firestore.BatchGetDocuments].
+message BatchGetDocumentsResponse {
+  // A single result.
+  // This can be empty if the server is just returning a transaction.
+  oneof result {
+    // A document that was requested.
+    Document found = 1;
+
+    // A document name that was requested but does not exist. In the format:
+    // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+    string missing = 2;
+  }
+
+  // The transaction that was started as part of this request.
+  // Will only be set in the first response, and only if
+  // [BatchGetDocumentsRequest.new_transaction][google.firestore.v1beta1.BatchGetDocumentsRequest.new_transaction] was set in the request.
+  bytes transaction = 3;
+
+  // The time at which the document was read.
+  // This may be monotically increasing, in this case the previous documents in
+  // the result stream are guaranteed not to have changed between their
+  // read_time and this one.
+  google.protobuf.Timestamp read_time = 4;
+}
+
+// The request for [Firestore.BeginTransaction][google.firestore.v1beta1.Firestore.BeginTransaction].
+message BeginTransactionRequest {
+  // The database name. In the format:
+  // `projects/{project_id}/databases/{database_id}`.
+  string database = 1;
+
+  // The options for the transaction.
+  // Defaults to a read-write transaction.
+  TransactionOptions options = 2;
+}
+
+// The response for [Firestore.BeginTransaction][google.firestore.v1beta1.Firestore.BeginTransaction].
+message BeginTransactionResponse {
+  // The transaction that was started.
+  bytes transaction = 1;
+}
+
+// The request for [Firestore.Commit][google.firestore.v1beta1.Firestore.Commit].
+message CommitRequest {
+  // The database name. In the format:
+  // `projects/{project_id}/databases/{database_id}`.
+  string database = 1;
+
+  // The writes to apply.
+  //
+  // Always executed atomically and in order.
+  repeated Write writes = 2;
+
+  // If set, applies all writes in this transaction, and commits it.
+  bytes transaction = 3;
+}
+
+// The response for [Firestore.Commit][google.firestore.v1beta1.Firestore.Commit].
+message CommitResponse {
+  // The result of applying the writes.
+  //
+  // This i-th write result corresponds to the i-th write in the
+  // request.
+  repeated WriteResult write_results = 1;
+
+  // The time at which the commit occurred.
+  google.protobuf.Timestamp commit_time = 2;
+}
+
+// The request for [Firestore.Rollback][google.firestore.v1beta1.Firestore.Rollback].
+message RollbackRequest {
+  // The database name. In the format:
+  // `projects/{project_id}/databases/{database_id}`.
+  string database = 1;
+
+  // The transaction to roll back.
+  bytes transaction = 2;
+}
+
+// The request for [Firestore.RunQuery][google.firestore.v1beta1.Firestore.RunQuery].
+message RunQueryRequest {
+  // The parent resource name. In the format:
+  // `projects/{project_id}/databases/{database_id}/documents` or
+  // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+  // For example:
+  // `projects/my-project/databases/my-database/documents` or
+  // `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom`
+  string parent = 1;
+
+  // The query to run.
+  oneof query_type {
+    // A structured query.
+    StructuredQuery structured_query = 2;
+  }
+
+  // The consistency mode for this transaction.
+  // If not set, defaults to strong consistency.
+  oneof consistency_selector {
+    // Reads documents in a transaction.
+    bytes transaction = 5;
+
+    // Starts a new transaction and reads the documents.
+    // Defaults to a read-only transaction.
+    // The new transaction ID will be returned as the first response in the
+    // stream.
+    TransactionOptions new_transaction = 6;
+
+    // Reads documents as they were at the given time.
+    // This may not be older than 60 seconds.
+    google.protobuf.Timestamp read_time = 7;
+  }
+}
+
+// The response for [Firestore.RunQuery][google.firestore.v1beta1.Firestore.RunQuery].
+message RunQueryResponse {
+  // The transaction that was started as part of this request.
+  // Can only be set in the first response, and only if
+  // [RunQueryRequest.new_transaction][google.firestore.v1beta1.RunQueryRequest.new_transaction] was set in the request.
+  // If set, no other fields will be set in this response.
+  bytes transaction = 2;
+
+  // A query result.
+  // Not set when reporting partial progress.
+  Document document = 1;
+
+  // The time at which the document was read. This may be monotonically
+  // increasing; in this case, the previous documents in the result stream are
+  // guaranteed not to have changed between their `read_time` and this one.
+  //
+  // If the query returns no results, a response with `read_time` and no
+  // `document` will be sent, and this represents the time at which the query
+  // was run.
+  google.protobuf.Timestamp read_time = 3;
+
+  // The number of results that have been skipped due to an offset between
+  // the last response and the current response.
+  int32 skipped_results = 4;
+}
+
+// The request for [Firestore.Write][google.firestore.v1beta1.Firestore.Write].
+//
+// The first request creates a stream, or resumes an existing one from a token.
+//
+// When creating a new stream, the server replies with a response containing
+// only an ID and a token, to use in the next request.
+//
+// When resuming a stream, the server first streams any responses later than the
+// given token, then a response containing only an up-to-date token, to use in
+// the next request.
+message WriteRequest {
+  // The database name. In the format:
+  // `projects/{project_id}/databases/{database_id}`.
+  // This is only required in the first message.
+  string database = 1;
+
+  // The ID of the write stream to resume.
+  // This may only be set in the first message. When left empty, a new write
+  // stream will be created.
+  string stream_id = 2;
+
+  // The writes to apply.
+  //
+  // Always executed atomically and in order.
+  // This must be empty on the first request.
+  // This may be empty on the last request.
+  // This must not be empty on all other requests.
+  repeated Write writes = 3;
+
+  // A stream token that was previously sent by the server.
+  //
+  // The client should set this field to the token from the most recent
+  // [WriteResponse][google.firestore.v1beta1.WriteResponse] it has received. This acknowledges that the client has
+  // received responses up to this token. After sending this token, earlier
+  // tokens may not be used anymore.
+  //
+  // The server may close the stream if there are too many unacknowledged
+  // responses.
+  //
+  // Leave this field unset when creating a new stream. To resume a stream at
+  // a specific point, set this field and the `stream_id` field.
+  //
+  // Leave this field unset when creating a new stream.
+  bytes stream_token = 4;
+
+  // Labels associated with this write request.
+  map<string, string> labels = 5;
+}
+
+// The response for [Firestore.Write][google.firestore.v1beta1.Firestore.Write].
+message WriteResponse {
+  // The ID of the stream.
+  // Only set on the first message, when a new stream was created.
+  string stream_id = 1;
+
+  // A token that represents the position of this response in the stream.
+  // This can be used by a client to resume the stream at this point.
+  //
+  // This field is always set.
+  bytes stream_token = 2;
+
+  // The result of applying the writes.
+  //
+  // This i-th write result corresponds to the i-th write in the
+  // request.
+  repeated WriteResult write_results = 3;
+
+  // The time at which the commit occurred.
+  google.protobuf.Timestamp commit_time = 4;
+}
+
+// A request for [Firestore.Listen][google.firestore.v1beta1.Firestore.Listen]
+message ListenRequest {
+  // The database name. In the format:
+  // `projects/{project_id}/databases/{database_id}`.
+  string database = 1;
+
+  // The supported target changes.
+  oneof target_change {
+    // A target to add to this stream.
+    Target add_target = 2;
+
+    // The ID of a target to remove from this stream.
+    int32 remove_target = 3;
+  }
+
+  // Labels associated with this target change.
+  map<string, string> labels = 4;
+}
+
+// The response for [Firestore.Listen][google.firestore.v1beta1.Firestore.Listen].
+message ListenResponse {
+  // The supported responses.
+  oneof response_type {
+    // Targets have changed.
+    TargetChange target_change = 2;
+
+    // A [Document][google.firestore.v1beta1.Document] has changed.
+    DocumentChange document_change = 3;
+
+    // A [Document][google.firestore.v1beta1.Document] has been deleted.
+    DocumentDelete document_delete = 4;
+
+    // A [Document][google.firestore.v1beta1.Document] has been removed from a target (because it is no longer
+    // relevant to that target).
+    DocumentRemove document_remove = 6;
+
+    // A filter to apply to the set of documents previously returned for the
+    // given target.
+    //
+    // Returned when documents may have been removed from the given target, but
+    // the exact documents are unknown.
+    ExistenceFilter filter = 5;
+  }
+}
+
+// A specification of a set of documents to listen to.
+message Target {
+  // A target specified by a set of documents names.
+  message DocumentsTarget {
+    // The names of the documents to retrieve. In the format:
+    // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+    // The request will fail if any of the document is not a child resource of
+    // the given `database`. Duplicate names will be elided.
+    repeated string documents = 2;
+  }
+
+  // A target specified by a query.
+  message QueryTarget {
+    // The parent resource name. In the format:
+    // `projects/{project_id}/databases/{database_id}/documents` or
+    // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+    // For example:
+    // `projects/my-project/databases/my-database/documents` or
+    // `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom`
+    string parent = 1;
+
+    // The query to run.
+    oneof query_type {
+      // A structured query.
+      StructuredQuery structured_query = 2;
+    }
+  }
+
+  // The type of target to listen to.
+  oneof target_type {
+    // A target specified by a query.
+    QueryTarget query = 2;
+
+    // A target specified by a set of document names.
+    DocumentsTarget documents = 3;
+  }
+
+  // When to start listening.
+  //
+  // If not specified, all matching Documents are returned before any
+  // subsequent changes.
+  oneof resume_type {
+    // A resume token from a prior [TargetChange][google.firestore.v1beta1.TargetChange] for an identical target.
+    //
+    // Using a resume token with a different target is unsupported and may fail.
+    bytes resume_token = 4;
+
+    // Start listening after a specific `read_time`.
+    //
+    // The client must know the state of matching documents at this time.
+    google.protobuf.Timestamp read_time = 11;
+  }
+
+  // A client provided target ID.
+  //
+  // If not set, the server will assign an ID for the target.
+  //
+  // Used for resuming a target without changing IDs. The IDs can either be
+  // client-assigned or be server-assigned in a previous stream. All targets
+  // with client provided IDs must be added before adding a target that needs
+  // a server-assigned id.
+  int32 target_id = 5;
+
+  // If the target should be removed once it is current and consistent.
+  bool once = 6;
+}
+
+// Targets being watched have changed.
+message TargetChange {
+  // The type of change.
+  enum TargetChangeType {
+    // No change has occurred. Used only to send an updated `resume_token`.
+    NO_CHANGE = 0;
+
+    // The targets have been added.
+    ADD = 1;
+
+    // The targets have been removed.
+    REMOVE = 2;
+
+    // The targets reflect all changes committed before the targets were added
+    // to the stream.
+    //
+    // This will be sent after or with a `read_time` that is greater than or
+    // equal to the time at which the targets were added.
+    //
+    // Listeners can wait for this change if read-after-write semantics
+    // are desired.
+    CURRENT = 3;
+
+    // The targets have been reset, and a new initial state for the targets
+    // will be returned in subsequent changes.
+    //
+    // After the initial state is complete, `CURRENT` will be returned even
+    // if the target was previously indicated to be `CURRENT`.
+    RESET = 4;
+  }
+
+  // The type of change that occurred.
+  TargetChangeType target_change_type = 1;
+
+  // The target IDs of targets that have changed.
+  //
+  // If empty, the change applies to all targets.
+  //
+  // For `target_change_type=ADD`, the order of the target IDs matches the order
+  // of the requests to add the targets. This allows clients to unambiguously
+  // associate server-assigned target IDs with added targets.
+  //
+  // For other states, the order of the target IDs is not defined.
+  repeated int32 target_ids = 2;
+
+  // The error that resulted in this change, if applicable.
+  google.rpc.Status cause = 3;
+
+  // A token that can be used to resume the stream for the given `target_ids`,
+  // or all targets if `target_ids` is empty.
+  //
+  // Not set on every target change.
+  bytes resume_token = 4;
+
+  // The consistent `read_time` for the given `target_ids` (omitted when the
+  // target_ids are not at a consistent snapshot).
+  //
+  // The stream is guaranteed to send a `read_time` with `target_ids` empty
+  // whenever the entire stream reaches a new consistent snapshot. ADD,
+  // CURRENT, and RESET messages are guaranteed to (eventually) result in a
+  // new consistent snapshot (while NO_CHANGE and REMOVE messages are not).
+  //
+  // For a given stream, `read_time` is guaranteed to be monotonically
+  // increasing.
+  google.protobuf.Timestamp read_time = 6;
+}
+
+// The request for [Firestore.ListCollectionIds][google.firestore.v1beta1.Firestore.ListCollectionIds].
+message ListCollectionIdsRequest {
+  // The parent document. In the format:
+  // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+  // For example:
+  // `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom`
+  string parent = 1;
+
+  // The maximum number of results to return.
+  int32 page_size = 2;
+
+  // A page token. Must be a value from
+  // [ListCollectionIdsResponse][google.firestore.v1beta1.ListCollectionIdsResponse].
+  string page_token = 3;
+}
+
+// The response from [Firestore.ListCollectionIds][google.firestore.v1beta1.Firestore.ListCollectionIds].
+message ListCollectionIdsResponse {
+  // The collection ids.
+  repeated string collection_ids = 1;
+
+  // A page token that may be used to continue the list.
+  string next_page_token = 2;
+}
diff --git a/firestore/google/cloud/firestore_v1beta1/proto/firestore_admin.proto b/firestore/google/cloud/firestore_v1beta1/proto/firestore_admin.proto
new file mode 100644
index 000000000000..15ce94da6b68
--- /dev/null
+++ b/firestore/google/cloud/firestore_v1beta1/proto/firestore_admin.proto
@@ -0,0 +1,365 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.firestore.admin.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/firestore/admin/v1beta1/index.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Firestore.Admin.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/firestore/admin/v1beta1;admin";
+option java_multiple_files = true;
+option java_outer_classname = "FirestoreAdminProto";
+option java_package = "com.google.firestore.admin.v1beta1";
+option objc_class_prefix = "GCFS";
+
+
+// The Cloud Firestore Admin API.
+//
+// This API provides several administrative services for Cloud Firestore.
+//
+// # Concepts
+//
+// Project, Database, Namespace, Collection, and Document are used as defined in
+// the Google Cloud Firestore API.
+//
+// Operation: An Operation represents work being performed in the background.
+//
+//
+// # Services
+//
+// ## Index
+//
+// The index service manages Cloud Firestore indexes.
+//
+// Index creation is performed asynchronously.
+// An Operation resource is created for each such asynchronous operation.
+// The state of the operation (including any errors encountered)
+// may be queried via the Operation resource.
+//
+// ## Metadata
+//
+// Provides metadata and statistical information about data in Cloud Firestore.
+// The data provided as part of this API may be stale.
+//
+// ## Operation
+//
+// The Operations collection provides a record of actions performed for the
+// specified Project (including any Operations in progress). Operations are not
+// created directly but through calls on other collections or resources.
+//
+// An Operation that is not yet done may be cancelled. The request to cancel is
+// asynchronous and the Operation may continue to run for some time after the
+// request to cancel is made.
+//
+// An Operation that is done may be deleted so that it is no longer listed as
+// part of the Operation collection.
+//
+// Operations are created by service `FirestoreAdmin`, but are accessed via
+// service `google.longrunning.Operations`.
+service FirestoreAdmin {
+  // Creates the specified index.
+  // A newly created index's initial state is `CREATING`. On completion of the
+  // returned [google.longrunning.Operation][google.longrunning.Operation], the state will be `READY`.
+  // If the index already exists, the call will return an `ALREADY_EXISTS`
+  // status.
+  //
+  // During creation, the process could result in an error, in which case the
+  // index will move to the `ERROR` state. The process can be recovered by
+  // fixing the data that caused the error, removing the index with
+  // [delete][google.firestore.admin.v1beta1.FirestoreAdmin.DeleteIndex], then re-creating the index with
+  // [create][google.firestore.admin.v1beta1.FirestoreAdmin.CreateIndex].
+  //
+  // Indexes with a single field cannot be created.
+  rpc CreateIndex(CreateIndexRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=projects/*/databases/*}/indexes"
+      body: "index"
+    };
+  }
+
+  // Lists the indexes that match the specified filters.
+  rpc ListIndexes(ListIndexesRequest) returns (ListIndexesResponse) {
+    option (google.api.http) = {
+      get: "/v1beta1/{parent=projects/*/databases/*}/indexes"
+    };
+  }
+
+  // Gets an index.
+  rpc GetIndex(GetIndexRequest) returns (Index) {
+    option (google.api.http) = {
+      get: "/v1beta1/{name=projects/*/databases/*/indexes/*}"
+    };
+  }
+
+  // Deletes an index.
+  rpc DeleteIndex(DeleteIndexRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1beta1/{name=projects/*/databases/*/indexes/*}"
+    };
+  }
+
+  // Exports a copy of all or a subset of documents from Google Cloud Firestore
+  // to another storage system, such as Google Cloud Storage. Recent updates to
+  // documents may not be reflected in the export. The export occurs in the
+  // background and its progress can be monitored and managed via the
+  // Operation resource that is created. The output of an export may only be
+  // used once the associated operation is done. If an export operation is
+  // cancelled before completion it may leave partial data behind in Google
+  // Cloud Storage.
+  rpc ExportDocuments(ExportDocumentsRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta1/{name=projects/*/databases/*}:exportDocuments"
+      body: "*"
+    };
+  }
+
+  // Imports documents into Google Cloud Firestore. Existing documents with the
+  // same name are overwritten. The import occurs in the background and its
+  // progress can be monitored and managed via the Operation resource that is
+  // created. If an ImportDocuments operation is cancelled, it is possible
+  // that a subset of the data has already been imported to Cloud Firestore.
+  rpc ImportDocuments(ImportDocumentsRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta1/{name=projects/*/databases/*}:importDocuments"
+      body: "*"
+    };
+  }
+}
+
+// Metadata for index operations. This metadata populates
+// the metadata field of [google.longrunning.Operation][google.longrunning.Operation].
+message IndexOperationMetadata {
+  // The type of index operation.
+  enum OperationType {
+    // Unspecified. Never set by server.
+    OPERATION_TYPE_UNSPECIFIED = 0;
+
+    // The operation is creating the index. Initiated by a `CreateIndex` call.
+    CREATING_INDEX = 1;
+  }
+
+  // The time that work began on the operation.
+  google.protobuf.Timestamp start_time = 1;
+
+  // The time the operation ended, either successfully or otherwise. Unset if
+  // the operation is still active.
+  google.protobuf.Timestamp end_time = 2;
+
+  // The index resource that this operation is acting on. For example:
+  // `projects/{project_id}/databases/{database_id}/indexes/{index_id}`
+  string index = 3;
+
+  // The type of index operation.
+  OperationType operation_type = 4;
+
+  // True if the [google.longrunning.Operation] was cancelled. If the
+  // cancellation is in progress, cancelled will be true but
+  // [google.longrunning.Operation.done][google.longrunning.Operation.done] will be false.
+  bool cancelled = 5;
+
+  // Progress of the existing operation, measured in number of documents.
+  Progress document_progress = 6;
+}
+
+// Measures the progress of a particular metric.
+message Progress {
+  // An estimate of how much work has been completed. Note that this may be
+  // greater than `work_estimated`.
+  int64 work_completed = 1;
+
+  // An estimate of how much work needs to be performed. Zero if the
+  // work estimate is unavailable. May change as work progresses.
+  int64 work_estimated = 2;
+}
+
+// The request for [FirestoreAdmin.CreateIndex][google.firestore.admin.v1beta1.FirestoreAdmin.CreateIndex].
+message CreateIndexRequest {
+  // The name of the database this index will apply to. For example:
+  // `projects/{project_id}/databases/{database_id}`
+  string parent = 1;
+
+  // The index to create. The name and state fields are output only and will be
+  // ignored. Certain single field indexes cannot be created or deleted.
+  Index index = 2;
+}
+
+// The request for [FirestoreAdmin.GetIndex][google.firestore.admin.v1beta1.FirestoreAdmin.GetIndex].
+message GetIndexRequest {
+  // The name of the index. For example:
+  // `projects/{project_id}/databases/{database_id}/indexes/{index_id}`
+  string name = 1;
+}
+
+// The request for [FirestoreAdmin.ListIndexes][google.firestore.admin.v1beta1.FirestoreAdmin.ListIndexes].
+message ListIndexesRequest {
+  // The database name. For example:
+  // `projects/{project_id}/databases/{database_id}`
+  string parent = 1;
+
+  string filter = 2;
+
+  // The standard List page size.
+  int32 page_size = 3;
+
+  // The standard List page token.
+  string page_token = 4;
+}
+
+// The request for [FirestoreAdmin.DeleteIndex][google.firestore.admin.v1beta1.FirestoreAdmin.DeleteIndex].
+message DeleteIndexRequest {
+  // The index name. For example:
+  // `projects/{project_id}/databases/{database_id}/indexes/{index_id}`
+  string name = 1;
+}
+
+// The response for [FirestoreAdmin.ListIndexes][google.firestore.admin.v1beta1.FirestoreAdmin.ListIndexes].
+message ListIndexesResponse {
+  // The indexes.
+  repeated Index indexes = 1;
+
+  // The standard List next-page token.
+  string next_page_token = 2;
+}
+
+// The request for [FirestoreAdmin.ExportDocuments][google.firestore.admin.v1beta1.FirestoreAdmin.ExportDocuments].
+message ExportDocumentsRequest {
+  // Database to export. Should be of the form:
+  // `projects/{project_id}/databases/{database_id}`.
+  string name = 1;
+
+  // Which collection ids to export. Unspecified means all collections.
+  repeated string collection_ids = 3;
+
+  // The output URI. Currently only supports Google Cloud Storage URIs of the
+  // form: `gs://BUCKET_NAME[/NAMESPACE_PATH]`, where `BUCKET_NAME` is the name
+  // of the Google Cloud Storage bucket and `NAMESPACE_PATH` is an optional
+  // Google Cloud Storage namespace path. When
+  // choosing a name, be sure to consider Google Cloud Storage naming
+  // guidelines: https://cloud.google.com/storage/docs/naming.
+  // If the URI is a bucket (without a namespace path), a prefix will be
+  // generated based on the start time.
+  string output_uri_prefix = 4;
+}
+
+// The request for [FirestoreAdmin.ImportDocuments][google.firestore.admin.v1beta1.FirestoreAdmin.ImportDocuments].
+message ImportDocumentsRequest {
+  // Database to import into. Should be of the form:
+  // `projects/{project_id}/databases/{database_id}`.
+  string name = 1;
+
+  // Which collection ids to import. Unspecified means all collections included
+  // in the import.
+  repeated string collection_ids = 3;
+
+  // Location of the exported files.
+  // This must match the output_uri_prefix of an ExportDocumentsResponse from
+  // an export that has completed successfully.
+  // See:
+  // [google.firestore.admin.v1beta1.ExportDocumentsResponse.output_uri_prefix][google.firestore.admin.v1beta1.ExportDocumentsResponse.output_uri_prefix].
+  string input_uri_prefix = 4;
+}
+
+// Returned in the [google.longrunning.Operation][google.longrunning.Operation] response field.
+message ExportDocumentsResponse {
+  // Location of the output files. This can be used to begin an import
+  // into Cloud Firestore (this project or another project) after the operation
+  // completes successfully.
+  string output_uri_prefix = 1;
+}
+
+// Metadata for ExportDocuments operations.
+message ExportDocumentsMetadata {
+  // The time that work began on the operation.
+  google.protobuf.Timestamp start_time = 1;
+
+  // The time the operation ended, either successfully or otherwise. Unset if
+  // the operation is still active.
+  google.protobuf.Timestamp end_time = 2;
+
+  // The state of the export operation.
+  OperationState operation_state = 3;
+
+  // An estimate of the number of documents processed.
+  Progress progress_documents = 4;
+
+  // An estimate of the number of bytes processed.
+  Progress progress_bytes = 5;
+
+  // Which collection ids are being exported.
+  repeated string collection_ids = 6;
+
+  // Where the entities are being exported to.
+  string output_uri_prefix = 7;
+}
+
+// Metadata for ImportDocuments operations.
+message ImportDocumentsMetadata {
+  // The time that work began on the operation.
+  google.protobuf.Timestamp start_time = 1;
+
+  // The time the operation ended, either successfully or otherwise. Unset if
+  // the operation is still active.
+  google.protobuf.Timestamp end_time = 2;
+
+  // The state of the import operation.
+  OperationState operation_state = 3;
+
+  // An estimate of the number of documents processed.
+  Progress progress_documents = 4;
+
+  // An estimate of the number of bytes processed.
+  Progress progress_bytes = 5;
+
+  // Which collection ids are being imported.
+  repeated string collection_ids = 6;
+
+  // The location of the documents being imported.
+  string input_uri_prefix = 7;
+}
+
+// The various possible states for an ongoing Operation.
+enum OperationState {
+  // Unspecified.
+  STATE_UNSPECIFIED = 0;
+
+  // Request is being prepared for processing.
+  INITIALIZING = 1;
+
+  // Request is actively being processed.
+  PROCESSING = 2;
+
+  // Request is in the process of being cancelled after user called
+  // google.longrunning.Operations.CancelOperation on the operation.
+  CANCELLING = 3;
+
+  // Request has been processed and is in its finalization stage.
+  FINALIZING = 4;
+
+  // Request has completed successfully.
+  SUCCESSFUL = 5;
+
+  // Request has finished being processed, but encountered an error.
+  FAILED = 6;
+
+  // Request has finished being cancelled after user called
+  // google.longrunning.Operations.CancelOperation.
+  CANCELLED = 7;
+}
diff --git a/firestore/google/cloud/firestore_v1beta1/proto/index.proto b/firestore/google/cloud/firestore_v1beta1/proto/index.proto
new file mode 100644
index 000000000000..c5784e0eaab7
--- /dev/null
+++ b/firestore/google/cloud/firestore_v1beta1/proto/index.proto
@@ -0,0 +1,102 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.firestore.admin.v1beta1;
+
+import "google/api/annotations.proto";
+
+option csharp_namespace = "Google.Cloud.Firestore.Admin.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/firestore/admin/v1beta1;admin";
+option java_multiple_files = true;
+option java_outer_classname = "IndexProto";
+option java_package = "com.google.firestore.admin.v1beta1";
+option objc_class_prefix = "GCFS";
+
+
+// A field of an index.
+message IndexField {
+  // The mode determines how a field is indexed.
+  enum Mode {
+    // The mode is unspecified.
+    MODE_UNSPECIFIED = 0;
+
+    // The field's values are indexed so as to support sequencing in
+    // ascending order and also query by <, >, <=, >=, and =.
+    ASCENDING = 2;
+
+    // The field's values are indexed so as to support sequencing in
+    // descending order and also query by <, >, <=, >=, and =.
+    DESCENDING = 3;
+
+    // The field's array values are indexed so as to support membership using
+    // ARRAY_CONTAINS queries.
+    ARRAY_CONTAINS = 4;
+  }
+
+  // The path of the field. Must match the field path specification described
+  // by [google.firestore.v1beta1.Document.fields][fields].
+  // Special field path `__name__` may be used by itself or at the end of a
+  // path. `__type__` may be used only at the end of path.
+  string field_path = 1;
+
+  // The field's mode.
+  Mode mode = 2;
+}
+
+// An index definition.
+message Index {
+  // The state of an index. During index creation, an index will be in the
+  // `CREATING` state. If the index is created successfully, it will transition
+  // to the `READY` state. If the index is not able to be created, it will
+  // transition to the `ERROR` state.
+  enum State {
+    // The state is unspecified.
+    STATE_UNSPECIFIED = 0;
+
+    // The index is being created.
+    // There is an active long-running operation for the index.
+    // The index is updated when writing a document.
+    // Some index data may exist.
+    CREATING = 3;
+
+    // The index is ready to be used.
+    // The index is updated when writing a document.
+    // The index is fully populated from all stored documents it applies to.
+    READY = 2;
+
+    // The index was being created, but something went wrong.
+    // There is no active long-running operation for the index,
+    // and the most recently finished long-running operation failed.
+    // The index is not updated when writing a document.
+    // Some index data may exist.
+    ERROR = 5;
+  }
+
+  // The resource name of the index.
+  // Output only.
+  string name = 1;
+
+  // The collection ID to which this index applies. Required.
+  string collection_id = 2;
+
+  // The fields to index.
+  repeated IndexField fields = 3;
+
+  // The state of the index.
+  // Output only.
+  State state = 6;
+}
diff --git a/firestore/google/cloud/firestore_v1beta1/proto/location.proto b/firestore/google/cloud/firestore_v1beta1/proto/location.proto
new file mode 100644
index 000000000000..db7e8544b709
--- /dev/null
+++ b/firestore/google/cloud/firestore_v1beta1/proto/location.proto
@@ -0,0 +1,34 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.firestore.admin.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/type/latlng.proto";
+
+option csharp_namespace = "Google.Cloud.Firestore.Admin.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/firestore/admin/v1beta1;admin";
+option java_multiple_files = true;
+option java_outer_classname = "LocationProto";
+option java_package = "com.google.firestore.admin.v1beta1";
+option objc_class_prefix = "GCFS";
+
+
+// The metadata message for [google.cloud.location.Location.metadata][google.cloud.location.Location.metadata].
+message LocationMetadata {
+
+}
diff --git a/firestore/google/cloud/firestore_v1beta1/proto/operation.proto b/firestore/google/cloud/firestore_v1beta1/proto/operation.proto
new file mode 100644
index 000000000000..c2a1b001e6a8
--- /dev/null
+++ b/firestore/google/cloud/firestore_v1beta1/proto/operation.proto
@@ -0,0 +1,203 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.firestore.admin.v1beta2;
+
+import "google/api/annotations.proto";
+import "google/firestore/admin/v1beta2/index.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Firestore.Admin.V1Beta2";
+option go_package = "google.golang.org/genproto/googleapis/firestore/admin/v1beta2;admin";
+option java_multiple_files = true;
+option java_outer_classname = "OperationProto";
+option java_package = "com.google.firestore.admin.v1beta2";
+option objc_class_prefix = "GCFS";
+
+
+// Metadata for [google.longrunning.Operation][google.longrunning.Operation] results from
+// [FirestoreAdmin.CreateIndex][google.firestore.admin.v1beta2.FirestoreAdmin.CreateIndex].
+message IndexOperationMetadata {
+  // The time this operation started.
+  google.protobuf.Timestamp start_time = 1;
+
+  // The time this operation completed. Will be unset if operation still in
+  // progress.
+  google.protobuf.Timestamp end_time = 2;
+
+  // The index resource that this operation is acting on. For example:
+  // `projects/{project_id}/databases/{database_id}/collectionGroups/{collection_id}/indexes/{index_id}`
+  string index = 3;
+
+  // The state of the operation.
+  OperationState state = 4;
+
+  // The progress, in documents, of this operation.
+  Progress progress_documents = 5;
+
+  // The progress, in bytes, of this operation.
+  Progress progress_bytes = 6;
+}
+
+// Metadata for [google.longrunning.Operation][google.longrunning.Operation] results from
+// [FirestoreAdmin.UpdateField][google.firestore.admin.v1beta2.FirestoreAdmin.UpdateField].
+message FieldOperationMetadata {
+  // Information about an index configuration change.
+  message IndexConfigDelta {
+    // Specifies how the index is changing.
+    enum ChangeType {
+      // The type of change is not specified or known.
+      CHANGE_TYPE_UNSPECIFIED = 0;
+
+      // The single field index is being added.
+      ADD = 1;
+
+      // The single field index is being removed.
+      REMOVE = 2;
+    }
+
+    // Specifies how the index is changing.
+    ChangeType change_type = 1;
+
+    // The index being changed.
+    Index index = 2;
+  }
+
+  // The time this operation started.
+  google.protobuf.Timestamp start_time = 1;
+
+  // The time this operation completed. Will be unset if operation still in
+  // progress.
+  google.protobuf.Timestamp end_time = 2;
+
+  // The field resource that this operation is acting on. For example:
+  // `projects/{project_id}/databases/{database_id}/collectionGroups/{collection_id}/fields/{field_path}`
+  string field = 3;
+
+  // A list of [IndexConfigDelta][google.firestore.admin.v1beta2.FieldOperationMetadata.IndexConfigDelta], which describe the intent of this
+  // operation.
+  repeated IndexConfigDelta index_config_deltas = 4;
+
+  // The state of the operation.
+  OperationState state = 5;
+
+  // The progress, in documents, of this operation.
+  Progress document_progress = 6;
+
+  // The progress, in bytes, of this operation.
+  Progress bytes_progress = 7;
+}
+
+// Metadata for [google.longrunning.Operation][google.longrunning.Operation] results from
+// [FirestoreAdmin.ExportDocuments][google.firestore.admin.v1beta2.FirestoreAdmin.ExportDocuments].
+message ExportDocumentsMetadata {
+  // The time this operation started.
+  google.protobuf.Timestamp start_time = 1;
+
+  // The time this operation completed. Will be unset if operation still in
+  // progress.
+  google.protobuf.Timestamp end_time = 2;
+
+  // The state of the export operation.
+  OperationState operation_state = 3;
+
+  // The progress, in documents, of this operation.
+  Progress progress_documents = 4;
+
+  // The progress, in bytes, of this operation.
+  Progress progress_bytes = 5;
+
+  // Which collection ids are being exported.
+  repeated string collection_ids = 6;
+
+  // Where the entities are being exported to.
+  string output_uri_prefix = 7;
+}
+
+// Metadata for [google.longrunning.Operation][google.longrunning.Operation] results from
+// [FirestoreAdmin.ImportDocuments][google.firestore.admin.v1beta2.FirestoreAdmin.ImportDocuments].
+message ImportDocumentsMetadata {
+  // The time this operation started.
+  google.protobuf.Timestamp start_time = 1;
+
+  // The time this operation completed. Will be unset if operation still in
+  // progress.
+  google.protobuf.Timestamp end_time = 2;
+
+  // The state of the import operation.
+  OperationState operation_state = 3;
+
+  // The progress, in documents, of this operation.
+  Progress progress_documents = 4;
+
+  // The progress, in bytes, of this operation.
+  Progress progress_bytes = 5;
+
+  // Which collection ids are being imported.
+  repeated string collection_ids = 6;
+
+  // The location of the documents being imported.
+  string input_uri_prefix = 7;
+}
+
+// Returned in the [google.longrunning.Operation][google.longrunning.Operation] response field.
+message ExportDocumentsResponse {
+  // Location of the output files. This can be used to begin an import
+  // into Cloud Firestore (this project or another project) after the operation
+  // completes successfully.
+  string output_uri_prefix = 1;
+}
+
+// Describes the progress of the operation.
+// Unit of work is generic and must be interpreted based on where [Progress][google.firestore.admin.v1beta2.Progress]
+// is used.
+message Progress {
+  // The amount of work estimated.
+  int64 estimated_work = 1;
+
+  // The amount of work completed.
+  int64 completed_work = 2;
+}
+
+// Describes the state of the operation.
+enum OperationState {
+  // Unspecified.
+  OPERATION_STATE_UNSPECIFIED = 0;
+
+  // Request is being prepared for processing.
+  INITIALIZING = 1;
+
+  // Request is actively being processed.
+  PROCESSING = 2;
+
+  // Request is in the process of being cancelled after user called
+  // google.longrunning.Operations.CancelOperation on the operation.
+  CANCELLING = 3;
+
+  // Request has been processed and is in its finalization stage.
+  FINALIZING = 4;
+
+  // Request has completed successfully.
+  SUCCESSFUL = 5;
+
+  // Request has finished being processed, but encountered an error.
+  FAILED = 6;
+
+  // Request has finished being cancelled after user called
+  // google.longrunning.Operations.CancelOperation.
+  CANCELLED = 7;
+}
diff --git a/firestore/google/cloud/firestore_v1beta1/proto/query.proto b/firestore/google/cloud/firestore_v1beta1/proto/query.proto
new file mode 100644
index 000000000000..17e930213b37
--- /dev/null
+++ b/firestore/google/cloud/firestore_v1beta1/proto/query.proto
@@ -0,0 +1,236 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.firestore.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/firestore/v1beta1/document.proto";
+import "google/protobuf/wrappers.proto";
+
+option csharp_namespace = "Google.Cloud.Firestore.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/firestore/v1beta1;firestore";
+option java_multiple_files = true;
+option java_outer_classname = "QueryProto";
+option java_package = "com.google.firestore.v1beta1";
+option objc_class_prefix = "GCFS";
+option php_namespace = "Google\\Cloud\\Firestore\\V1beta1";
+
+
+// A Firestore query.
+message StructuredQuery {
+  // A selection of a collection, such as `messages as m1`.
+  message CollectionSelector {
+    // The collection ID.
+    // When set, selects only collections with this ID.
+    string collection_id = 2;
+
+    // When false, selects only collections that are immediate children of
+    // the `parent` specified in the containing `RunQueryRequest`.
+    // When true, selects all descendant collections.
+    bool all_descendants = 3;
+  }
+
+  // A filter.
+  message Filter {
+    // The type of filter.
+    oneof filter_type {
+      // A composite filter.
+      CompositeFilter composite_filter = 1;
+
+      // A filter on a document field.
+      FieldFilter field_filter = 2;
+
+      // A filter that takes exactly one argument.
+      UnaryFilter unary_filter = 3;
+    }
+  }
+
+  // A filter that merges multiple other filters using the given operator.
+  message CompositeFilter {
+    // A composite filter operator.
+    enum Operator {
+      // Unspecified. This value must not be used.
+      OPERATOR_UNSPECIFIED = 0;
+
+      // The results are required to satisfy each of the combined filters.
+      AND = 1;
+    }
+
+    // The operator for combining multiple filters.
+    Operator op = 1;
+
+    // The list of filters to combine.
+    // Must contain at least one filter.
+    repeated Filter filters = 2;
+  }
+
+  // A filter on a specific field.
+  message FieldFilter {
+    // A field filter operator.
+    enum Operator {
+      // Unspecified. This value must not be used.
+      OPERATOR_UNSPECIFIED = 0;
+
+      // Less than. Requires that the field come first in `order_by`.
+      LESS_THAN = 1;
+
+      // Less than or equal. Requires that the field come first in `order_by`.
+      LESS_THAN_OR_EQUAL = 2;
+
+      // Greater than. Requires that the field come first in `order_by`.
+      GREATER_THAN = 3;
+
+      // Greater than or equal. Requires that the field come first in
+      // `order_by`.
+      GREATER_THAN_OR_EQUAL = 4;
+
+      // Equal.
+      EQUAL = 5;
+
+      // Contains. Requires that the field is an array.
+      ARRAY_CONTAINS = 7;
+    }
+
+    // The field to filter by.
+    FieldReference field = 1;
+
+    // The operator to filter by.
+    Operator op = 2;
+
+    // The value to compare to.
+    Value value = 3;
+  }
+
+  // A filter with a single operand.
+  message UnaryFilter {
+    // A unary operator.
+    enum Operator {
+      // Unspecified. This value must not be used.
+      OPERATOR_UNSPECIFIED = 0;
+
+      // Test if a field is equal to NaN.
+      IS_NAN = 2;
+
+      // Test if an exprestion evaluates to Null.
+      IS_NULL = 3;
+    }
+
+    // The unary operator to apply.
+    Operator op = 1;
+
+    // The argument to the filter.
+    oneof operand_type {
+      // The field to which to apply the operator.
+      FieldReference field = 2;
+    }
+  }
+
+  // An order on a field.
+  message Order {
+    // The field to order by.
+    FieldReference field = 1;
+
+    // The direction to order by. Defaults to `ASCENDING`.
+    Direction direction = 2;
+  }
+
+  // A reference to a field, such as `max(messages.time) as max_time`.
+  message FieldReference {
+    string field_path = 2;
+  }
+
+  // The projection of document's fields to return.
+  message Projection {
+    // The fields to return.
+    //
+    // If empty, all fields are returned. To only return the name
+    // of the document, use `['__name__']`.
+    repeated FieldReference fields = 2;
+  }
+
+  // A sort direction.
+  enum Direction {
+    // Unspecified.
+    DIRECTION_UNSPECIFIED = 0;
+
+    // Ascending.
+    ASCENDING = 1;
+
+    // Descending.
+    DESCENDING = 2;
+  }
+
+  // The projection to return.
+  Projection select = 1;
+
+  // The collections to query.
+  repeated CollectionSelector from = 2;
+
+  // The filter to apply.
+  Filter where = 3;
+
+  // The order to apply to the query results.
+  //
+  // Firestore guarantees a stable ordering through the following rules:
+  //
+  //  * Any field required to appear in `order_by`, that is not already
+  //    specified in `order_by`, is appended to the order in field name order
+  //    by default.
+  //  * If an order on `__name__` is not specified, it is appended by default.
+  //
+  // Fields are appended with the same sort direction as the last order
+  // specified, or 'ASCENDING' if no order was specified. For example:
+  //
+  //  * `SELECT * FROM Foo ORDER BY A` becomes
+  //    `SELECT * FROM Foo ORDER BY A, __name__`
+  //  * `SELECT * FROM Foo ORDER BY A DESC` becomes
+  //    `SELECT * FROM Foo ORDER BY A DESC, __name__ DESC`
+  //  * `SELECT * FROM Foo WHERE A > 1` becomes
+  //    `SELECT * FROM Foo WHERE A > 1 ORDER BY A, __name__`
+  repeated Order order_by = 4;
+
+  // A starting point for the query results.
+  Cursor start_at = 7;
+
+  // A end point for the query results.
+  Cursor end_at = 8;
+
+  // The number of results to skip.
+  //
+  // Applies before limit, but after all other constraints. Must be >= 0 if
+  // specified.
+  int32 offset = 6;
+
+  // The maximum number of results to return.
+  //
+  // Applies after all other constraints.
+  // Must be >= 0 if specified.
+  google.protobuf.Int32Value limit = 5;
+}
+
+// A position in a query result set.
+message Cursor {
+  // The values that represent a position, in the order they appear in
+  // the order by clause of a query.
+  //
+  // Can contain fewer values than specified in the order by clause.
+  repeated Value values = 1;
+
+  // If the position is just before or just after the given values, relative
+  // to the sort order defined by the query.
+  bool before = 2;
+}
diff --git a/firestore/google/cloud/firestore_v1beta1/proto/write.proto b/firestore/google/cloud/firestore_v1beta1/proto/write.proto
new file mode 100644
index 000000000000..98cd6cbbcff9
--- /dev/null
+++ b/firestore/google/cloud/firestore_v1beta1/proto/write.proto
@@ -0,0 +1,255 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.firestore.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/firestore/v1beta1/common.proto";
+import "google/firestore/v1beta1/document.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Firestore.V1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/firestore/v1beta1;firestore";
+option java_multiple_files = true;
+option java_outer_classname = "WriteProto";
+option java_package = "com.google.firestore.v1beta1";
+option objc_class_prefix = "GCFS";
+option php_namespace = "Google\\Cloud\\Firestore\\V1beta1";
+
+
+// A write on a document.
+message Write {
+  // The operation to execute.
+  oneof operation {
+    // A document to write.
+    Document update = 1;
+
+    // A document name to delete. In the format:
+    // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
+    string delete = 2;
+
+    // Applies a tranformation to a document.
+    // At most one `transform` per document is allowed in a given request.
+    // An `update` cannot follow a `transform` on the same document in a given
+    // request.
+    DocumentTransform transform = 6;
+  }
+
+  // The fields to update in this write.
+  //
+  // This field can be set only when the operation is `update`.
+  // If the mask is not set for an `update` and the document exists, any
+  // existing data will be overwritten.
+  // If the mask is set and the document on the server has fields not covered by
+  // the mask, they are left unchanged.
+  // Fields referenced in the mask, but not present in the input document, are
+  // deleted from the document on the server.
+  // The field paths in this mask must not contain a reserved field name.
+  DocumentMask update_mask = 3;
+
+  // An optional precondition on the document.
+  //
+  // The write will fail if this is set and not met by the target document.
+  Precondition current_document = 4;
+}
+
+// A transformation of a document.
+message DocumentTransform {
+  // A transformation of a field of the document.
+  message FieldTransform {
+    // A value that is calculated by the server.
+    enum ServerValue {
+      // Unspecified. This value must not be used.
+      SERVER_VALUE_UNSPECIFIED = 0;
+
+      // The time at which the server processed the request, with millisecond
+      // precision.
+      REQUEST_TIME = 1;
+    }
+
+    // The path of the field. See [Document.fields][google.firestore.v1beta1.Document.fields] for the field path syntax
+    // reference.
+    string field_path = 1;
+
+    // The transformation to apply on the field.
+    oneof transform_type {
+      // Sets the field to the given server value.
+      ServerValue set_to_server_value = 2;
+
+      // Adds the given value to the field's current value.
+      //
+      // This must be an integer or a double value.
+      // If the field is not an integer or double, or if the field does not yet
+      // exist, the transformation will set the field to the given value.
+      // If either of the given value or the current field value are doubles,
+      // both values will be interpreted as doubles. Double arithmetic and
+      // representation of double values follow IEEE 754 semantics.
+      // If there is positive/negative integer overflow, the field is resolved
+      // to the largest magnitude positive/negative integer.
+      Value increment = 3;
+
+      // Sets the field to the maximum of its current value and the given value.
+      //
+      // This must be an integer or a double value.
+      // If the field is not an integer or double, or if the field does not yet
+      // exist, the transformation will set the field to the given value.
+      // If a maximum operation is applied where the field and the input value
+      // are of mixed types (that is - one is an integer and one is a double)
+      // the field takes on the type of the larger operand. If the operands are
+      // equivalent (e.g. 3 and 3.0), the field does not change.
+      // 0, 0.0, and -0.0 are all zero. The maximum of a zero stored value and
+      // zero input value is always the stored value.
+      // The maximum of any numeric value x and NaN is NaN.
+      Value maximum = 4;
+
+      // Sets the field to the minimum of its current value and the given value.
+      //
+      // This must be an integer or a double value.
+      // If the field is not an integer or double, or if the field does not yet
+      // exist, the transformation will set the field to the input value.
+      // If a minimum operation is applied where the field and the input value
+      // are of mixed types (that is - one is an integer and one is a double)
+      // the field takes on the type of the smaller operand. If the operands are
+      // equivalent (e.g. 3 and 3.0), the field does not change.
+      // 0, 0.0, and -0.0 are all zero. The minimum of a zero stored value and
+      // zero input value is always the stored value.
+      // The minimum of any numeric value x and NaN is NaN.
+      Value minimum = 5;
+
+      // Append the given elements in order if they are not already present in
+      // the current field value.
+      // If the field is not an array, or if the field does not yet exist, it is
+      // first set to the empty array.
+      //
+      // Equivalent numbers of different types (e.g. 3L and 3.0) are
+      // considered equal when checking if a value is missing.
+      // NaN is equal to NaN, and Null is equal to Null.
+      // If the input contains multiple equivalent values, only the first will
+      // be considered.
+      //
+      // The corresponding transform_result will be the null value.
+      ArrayValue append_missing_elements = 6;
+
+      // Remove all of the given elements from the array in the field.
+      // If the field is not an array, or if the field does not yet exist, it is
+      // set to the empty array.
+      //
+      // Equivalent numbers of the different types (e.g. 3L and 3.0) are
+      // considered equal when deciding whether an element should be removed.
+      // NaN is equal to NaN, and Null is equal to Null.
+      // This will remove all equivalent values if there are duplicates.
+      //
+      // The corresponding transform_result will be the null value.
+      ArrayValue remove_all_from_array = 7;
+    }
+  }
+
+  // The name of the document to transform.
+  string document = 1;
+
+  // The list of transformations to apply to the fields of the document, in
+  // order.
+  // This must not be empty.
+  repeated FieldTransform field_transforms = 2;
+}
+
+// The result of applying a write.
+message WriteResult {
+  // The last update time of the document after applying the write. Not set
+  // after a `delete`.
+  //
+  // If the write did not actually change the document, this will be the
+  // previous update_time.
+  google.protobuf.Timestamp update_time = 1;
+
+  // The results of applying each [DocumentTransform.FieldTransform][google.firestore.v1beta1.DocumentTransform.FieldTransform], in the
+  // same order.
+  repeated Value transform_results = 2;
+}
+
+// A [Document][google.firestore.v1beta1.Document] has changed.
+//
+// May be the result of multiple [writes][google.firestore.v1beta1.Write], including deletes, that
+// ultimately resulted in a new value for the [Document][google.firestore.v1beta1.Document].
+//
+// Multiple [DocumentChange][google.firestore.v1beta1.DocumentChange] messages may be returned for the same logical
+// change, if multiple targets are affected.
+message DocumentChange {
+  // The new state of the [Document][google.firestore.v1beta1.Document].
+  //
+  // If `mask` is set, contains only fields that were updated or added.
+  Document document = 1;
+
+  // A set of target IDs of targets that match this document.
+  repeated int32 target_ids = 5;
+
+  // A set of target IDs for targets that no longer match this document.
+  repeated int32 removed_target_ids = 6;
+}
+
+// A [Document][google.firestore.v1beta1.Document] has been deleted.
+//
+// May be the result of multiple [writes][google.firestore.v1beta1.Write], including updates, the
+// last of which deleted the [Document][google.firestore.v1beta1.Document].
+//
+// Multiple [DocumentDelete][google.firestore.v1beta1.DocumentDelete] messages may be returned for the same logical
+// delete, if multiple targets are affected.
+message DocumentDelete {
+  // The resource name of the [Document][google.firestore.v1beta1.Document] that was deleted.
+  string document = 1;
+
+  // A set of target IDs for targets that previously matched this entity.
+  repeated int32 removed_target_ids = 6;
+
+  // The read timestamp at which the delete was observed.
+  //
+  // Greater or equal to the `commit_time` of the delete.
+  google.protobuf.Timestamp read_time = 4;
+}
+
+// A [Document][google.firestore.v1beta1.Document] has been removed from the view of the targets.
+//
+// Sent if the document is no longer relevant to a target and is out of view.
+// Can be sent instead of a DocumentDelete or a DocumentChange if the server
+// can not send the new value of the document.
+//
+// Multiple [DocumentRemove][google.firestore.v1beta1.DocumentRemove] messages may be returned for the same logical
+// write or delete, if multiple targets are affected.
+message DocumentRemove {
+  // The resource name of the [Document][google.firestore.v1beta1.Document] that has gone out of view.
+  string document = 1;
+
+  // A set of target IDs for targets that previously matched this document.
+  repeated int32 removed_target_ids = 2;
+
+  // The read timestamp at which the remove was observed.
+  //
+  // Greater or equal to the `commit_time` of the change/delete/remove.
+  google.protobuf.Timestamp read_time = 4;
+}
+
+// A digest of all the documents that match a given target.
+message ExistenceFilter {
+  // The target ID to which this filter applies.
+  int32 target_id = 1;
+
+  // The total count of documents that match [target_id][google.firestore.v1beta1.ExistenceFilter.target_id].
+  //
+  // If different from the count of documents in the client that match, the
+  // client must manually determine which documents no longer match the target.
+  int32 count = 2;
+}
diff --git a/firestore/synth.metadata b/firestore/synth.metadata
index 1fc0091661a8..6d4f585d9195 100644
--- a/firestore/synth.metadata
+++ b/firestore/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:19:08.983321Z",
+  "updateTime": "2019-01-23T23:44:19.085946Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/firestore/synth.py b/firestore/synth.py
index 5a5972e56776..71ca5de6f47e 100644
--- a/firestore/synth.py
+++ b/firestore/synth.py
@@ -27,6 +27,7 @@
     "v1beta1",
     config_path="/google/firestore/artman_firestore.yaml",
     artman_output_name="firestore-v1beta1",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/firestore_v1beta1/proto")
diff --git a/iam/google/cloud/iam_credentials_v1/proto/common.proto b/iam/google/cloud/iam_credentials_v1/proto/common.proto
new file mode 100644
index 000000000000..fa382a99ec4a
--- /dev/null
+++ b/iam/google/cloud/iam_credentials_v1/proto/common.proto
@@ -0,0 +1,224 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.iam.credentials.v1;
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/iam/credentials/v1;credentials";
+option java_multiple_files = true;
+option java_outer_classname = "IAMCredentialsCommonProto";
+option java_package = "com.google.cloud.iam.credentials.v1";
+
+
+message GenerateAccessTokenRequest {
+  // The resource name of the service account for which the credentials
+  // are requested, in the following format:
+  // `projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}`.
+  string name = 1;
+
+  // The sequence of service accounts in a delegation chain. Each service
+  // account must be granted the `roles/iam.serviceAccountTokenCreator` role
+  // on its next service account in the chain. The last service account in the
+  // chain must be granted the `roles/iam.serviceAccountTokenCreator` role
+  // on the service account that is specified in the `name` field of the
+  // request.
+  //
+  // The delegates must have the following format:
+  // `projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}`
+  repeated string delegates = 2;
+
+  // Code to identify the scopes to be included in the OAuth 2.0 access token.
+  // See https://developers.google.com/identity/protocols/googlescopes for more
+  // information.
+  // At least one value required.
+  repeated string scope = 4;
+
+  // The desired lifetime duration of the access token in seconds.
+  // Must be set to a value less than or equal to 3600 (1 hour). If a value is
+  // not specified, the token's lifetime will be set to a default value of one
+  // hour.
+  google.protobuf.Duration lifetime = 7;
+}
+
+message GenerateAccessTokenResponse {
+  // The OAuth 2.0 access token.
+  string access_token = 1;
+
+  // Token expiration time.
+  // The expiration time is always set.
+  google.protobuf.Timestamp expire_time = 3;
+}
+
+message SignBlobRequest {
+  // The resource name of the service account for which the credentials
+  // are requested, in the following format:
+  // `projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}`.
+  string name = 1;
+
+  // The sequence of service accounts in a delegation chain. Each service
+  // account must be granted the `roles/iam.serviceAccountTokenCreator` role
+  // on its next service account in the chain. The last service account in the
+  // chain must be granted the `roles/iam.serviceAccountTokenCreator` role
+  // on the service account that is specified in the `name` field of the
+  // request.
+  //
+  // The delegates must have the following format:
+  // `projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}`
+  repeated string delegates = 3;
+
+  // The bytes to sign.
+  bytes payload = 5;
+}
+
+message SignBlobResponse {
+  // The ID of the key used to sign the blob.
+  string key_id = 1;
+
+  // The signed blob.
+  bytes signed_blob = 4;
+}
+
+message SignJwtRequest {
+  // The resource name of the service account for which the credentials
+  // are requested, in the following format:
+  // `projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}`.
+  string name = 1;
+
+  // The sequence of service accounts in a delegation chain. Each service
+  // account must be granted the `roles/iam.serviceAccountTokenCreator` role
+  // on its next service account in the chain. The last service account in the
+  // chain must be granted the `roles/iam.serviceAccountTokenCreator` role
+  // on the service account that is specified in the `name` field of the
+  // request.
+  //
+  // The delegates must have the following format:
+  // `projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}`
+  repeated string delegates = 3;
+
+  // The JWT payload to sign: a JSON object that contains a JWT Claims Set.
+  string payload = 5;
+}
+
+message SignJwtResponse {
+  // The ID of the key used to sign the JWT.
+  string key_id = 1;
+
+  // The signed JWT.
+  string signed_jwt = 2;
+}
+
+message GenerateIdTokenRequest {
+  // The resource name of the service account for which the credentials
+  // are requested, in the following format:
+  // `projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}`.
+  string name = 1;
+
+  // The sequence of service accounts in a delegation chain. Each service
+  // account must be granted the `roles/iam.serviceAccountTokenCreator` role
+  // on its next service account in the chain. The last service account in the
+  // chain must be granted the `roles/iam.serviceAccountTokenCreator` role
+  // on the service account that is specified in the `name` field of the
+  // request.
+  //
+  // The delegates must have the following format:
+  // `projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}`
+  repeated string delegates = 2;
+
+  // The audience for the token, such as the API or account that this token
+  // grants access to.
+  string audience = 3;
+
+  // Include the service account email in the token. If set to `true`, the
+  // token will contain `email` and `email_verified` claims.
+  bool include_email = 4;
+}
+
+message GenerateIdTokenResponse {
+  // The OpenId Connect ID token.
+  string token = 1;
+}
+
+message GenerateIdentityBindingAccessTokenRequest {
+  // The resource name of the service account for which the credentials
+  // are requested, in the following format:
+  // `projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}`.
+  string name = 1;
+
+  // Code to identify the scopes to be included in the OAuth 2.0 access token.
+  // See https://developers.google.com/identity/protocols/googlescopes for more
+  // information.
+  // At least one value required.
+  repeated string scope = 2;
+
+  // Required. Input token.
+  // Must be in JWT format according to
+  // RFC7523 (https://tools.ietf.org/html/rfc7523)
+  // and must have 'kid' field in the header.
+  // Supported signing algorithms: RS256 (RS512, ES256, ES512 coming soon).
+  // Mandatory payload fields (along the lines of RFC 7523, section 3):
+  // - iss: issuer of the token. Must provide a discovery document at
+  //        $iss/.well-known/openid-configuration . The document needs to be
+  //        formatted according to section 4.2 of the OpenID Connect Discovery
+  //        1.0 specification.
+  // - iat: Issue time in seconds since epoch. Must be in the past.
+  // - exp: Expiration time in seconds since epoch. Must be less than 48 hours
+  //        after iat. We recommend to create tokens that last shorter than 6
+  //        hours to improve security unless business reasons mandate longer
+  //        expiration times. Shorter token lifetimes are generally more secure
+  //        since tokens that have been exfiltrated by attackers can be used for
+  //        a shorter time. you can configure the maximum lifetime of the
+  //        incoming token in the configuration of the mapper.
+  //        The resulting Google token will expire within an hour or at "exp",
+  //        whichever is earlier.
+  // - sub: JWT subject, identity asserted in the JWT.
+  // - aud: Configured in the mapper policy. By default the service account
+  //        email.
+  //
+  // Claims from the incoming token can be transferred into the output token
+  // accoding to the mapper configuration. The outgoing claim size is limited.
+  // Outgoing claims size must be less than 4kB serialized as JSON without
+  // whitespace.
+  //
+  // Example header:
+  // {
+  //   "alg": "RS256",
+  //   "kid": "92a4265e14ab04d4d228a48d10d4ca31610936f8"
+  // }
+  // Example payload:
+  // {
+  //   "iss": "https://accounts.google.com",
+  //   "iat": 1517963104,
+  //   "exp": 1517966704,
+  //   "aud": "https://iamcredentials.googleapis.com/",
+  //   "sub": "113475438248934895348",
+  //   "my_claims": {
+  //     "additional_claim": "value"
+  //   }
+  // }
+  string jwt = 3;
+}
+
+message GenerateIdentityBindingAccessTokenResponse {
+  // The OAuth 2.0 access token.
+  string access_token = 1;
+
+  // Token expiration time.
+  // The expiration time is always set.
+  google.protobuf.Timestamp expire_time = 2;
+}
diff --git a/iam/google/cloud/iam_credentials_v1/proto/iamcredentials.proto b/iam/google/cloud/iam_credentials_v1/proto/iamcredentials.proto
new file mode 100644
index 000000000000..91902dfd2b06
--- /dev/null
+++ b/iam/google/cloud/iam_credentials_v1/proto/iamcredentials.proto
@@ -0,0 +1,81 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.iam.credentials.v1;
+
+import "google/api/annotations.proto";
+import "google/iam/credentials/v1/common.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/iam/credentials/v1;credentials";
+option java_multiple_files = true;
+option java_outer_classname = "IAMCredentialsProto";
+option java_package = "com.google.cloud.iam.credentials.v1";
+
+
+// A service account is a special type of Google account that belongs to your
+// application or a virtual machine (VM), instead of to an individual end user.
+// Your application assumes the identity of the service account to call Google
+// APIs, so that the users aren't directly involved.
+//
+// Service account credentials are used to temporarily assume the identity
+// of the service account. Supported credential types include OAuth 2.0 access
+// tokens, OpenID Connect ID tokens, self-signed JSON Web Tokens (JWTs), and
+// more.
+service IAMCredentials {
+  // Generates an OAuth 2.0 access token for a service account.
+  rpc GenerateAccessToken(GenerateAccessTokenRequest) returns (GenerateAccessTokenResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/serviceAccounts/*}:generateAccessToken"
+      body: "*"
+    };
+  }
+
+  // Generates an OpenID Connect ID token for a service account.
+  rpc GenerateIdToken(GenerateIdTokenRequest) returns (GenerateIdTokenResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/serviceAccounts/*}:generateIdToken"
+      body: "*"
+    };
+  }
+
+  // Signs a blob using a service account's system-managed private key.
+  rpc SignBlob(SignBlobRequest) returns (SignBlobResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/serviceAccounts/*}:signBlob"
+      body: "*"
+    };
+  }
+
+  // Signs a JWT using a service account's system-managed private key.
+  rpc SignJwt(SignJwtRequest) returns (SignJwtResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/serviceAccounts/*}:signJwt"
+      body: "*"
+    };
+  }
+
+  // Exchange a JWT signed by third party identity provider to an OAuth 2.0
+  // access token
+  rpc GenerateIdentityBindingAccessToken(
+      GenerateIdentityBindingAccessTokenRequest)
+      returns (GenerateIdentityBindingAccessTokenResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/serviceAccounts/*}:generateIdentityBindingAccessToken"
+      body: "*"
+    };
+  }
+}
diff --git a/iam/synth.metadata b/iam/synth.metadata
index cab5dbc3f3d5..3b3e2787d654 100644
--- a/iam/synth.metadata
+++ b/iam/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:19:36.096921Z",
+  "updateTime": "2019-01-24T05:39:59.371229Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
@@ -28,7 +28,7 @@
     {
       "client": {
         "source": "googleapis",
-        "apiName": "iam",
+        "apiName": "iam_credentials",
         "apiVersion": "v1",
         "language": "python",
         "generator": "gapic",
diff --git a/iam/synth.py b/iam/synth.py
index d929c68b2e66..8c486fa26a0d 100644
--- a/iam/synth.py
+++ b/iam/synth.py
@@ -24,10 +24,11 @@
 # Generate automl GAPIC layer
 # ----------------------------------------------------------------------------
 library = gapic.py_library(
-    "iam",
+    "iam_credentials",
     "v1",
     config_path="/google/iam/credentials/artman_iamcredentials_v1.yaml",
-    artman_output_name="iamcredentials-v1"
+    artman_output_name="iamcredentials-v1",
+    include_protos=True,
 )
 
 excludes = [
diff --git a/iot/google/cloud/iot_v1/proto/device_manager.proto b/iot/google/cloud/iot_v1/proto/device_manager.proto
new file mode 100644
index 000000000000..12e5a973dd7f
--- /dev/null
+++ b/iot/google/cloud/iot_v1/proto/device_manager.proto
@@ -0,0 +1,556 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.iot.v1;
+
+import "google/api/annotations.proto";
+import "google/cloud/iot/v1/resources.proto";
+import "google/iam/v1/iam_policy.proto";
+import "google/iam/v1/policy.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/iot/v1;iot";
+option java_multiple_files = true;
+option java_outer_classname = "DeviceManagerProto";
+option java_package = "com.google.cloud.iot.v1";
+
+
+// Internet of Things (IoT) service. Securely connect and manage IoT devices.
+service DeviceManager {
+  // Creates a device registry that contains devices.
+  rpc CreateDeviceRegistry(CreateDeviceRegistryRequest) returns (DeviceRegistry) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/locations/*}/registries"
+      body: "device_registry"
+    };
+  }
+
+  // Gets a device registry configuration.
+  rpc GetDeviceRegistry(GetDeviceRegistryRequest) returns (DeviceRegistry) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/registries/*}"
+    };
+  }
+
+  // Updates a device registry configuration.
+  rpc UpdateDeviceRegistry(UpdateDeviceRegistryRequest) returns (DeviceRegistry) {
+    option (google.api.http) = {
+      patch: "/v1/{device_registry.name=projects/*/locations/*/registries/*}"
+      body: "device_registry"
+    };
+  }
+
+  // Deletes a device registry configuration.
+  rpc DeleteDeviceRegistry(DeleteDeviceRegistryRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1/{name=projects/*/locations/*/registries/*}"
+    };
+  }
+
+  // Lists device registries.
+  rpc ListDeviceRegistries(ListDeviceRegistriesRequest) returns (ListDeviceRegistriesResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/locations/*}/registries"
+    };
+  }
+
+  // Creates a device in a device registry.
+  rpc CreateDevice(CreateDeviceRequest) returns (Device) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/locations/*/registries/*}/devices"
+      body: "device"
+    };
+  }
+
+  // Gets details about a device.
+  rpc GetDevice(GetDeviceRequest) returns (Device) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/registries/*/devices/*}"
+      additional_bindings {
+        get: "/v1/{name=projects/*/locations/*/registries/*/groups/*/devices/*}"
+      }
+    };
+  }
+
+  // Updates a device.
+  rpc UpdateDevice(UpdateDeviceRequest) returns (Device) {
+    option (google.api.http) = {
+      patch: "/v1/{device.name=projects/*/locations/*/registries/*/devices/*}"
+      body: "device"
+      additional_bindings {
+        patch: "/v1/{device.name=projects/*/locations/*/registries/*/groups/*/devices/*}"
+        body: "device"
+      }
+    };
+  }
+
+  // Deletes a device.
+  rpc DeleteDevice(DeleteDeviceRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1/{name=projects/*/locations/*/registries/*/devices/*}"
+    };
+  }
+
+  // List devices in a device registry.
+  rpc ListDevices(ListDevicesRequest) returns (ListDevicesResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/locations/*/registries/*}/devices"
+      additional_bindings {
+        get: "/v1/{parent=projects/*/locations/*/registries/*/groups/*}/devices"
+      }
+    };
+  }
+
+  // Modifies the configuration for the device, which is eventually sent from
+  // the Cloud IoT Core servers. Returns the modified configuration version and
+  // its metadata.
+  rpc ModifyCloudToDeviceConfig(ModifyCloudToDeviceConfigRequest) returns (DeviceConfig) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/locations/*/registries/*/devices/*}:modifyCloudToDeviceConfig"
+      body: "*"
+      additional_bindings {
+        post: "/v1/{name=projects/*/locations/*/registries/*/groups/*/devices/*}:modifyCloudToDeviceConfig"
+        body: "*"
+      }
+    };
+  }
+
+  // Lists the last few versions of the device configuration in descending
+  // order (i.e.: newest first).
+  rpc ListDeviceConfigVersions(ListDeviceConfigVersionsRequest) returns (ListDeviceConfigVersionsResponse) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/registries/*/devices/*}/configVersions"
+      additional_bindings {
+        get: "/v1/{name=projects/*/locations/*/registries/*/groups/*/devices/*}/configVersions"
+      }
+    };
+  }
+
+  // Lists the last few versions of the device state in descending order (i.e.:
+  // newest first).
+  rpc ListDeviceStates(ListDeviceStatesRequest) returns (ListDeviceStatesResponse) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/registries/*/devices/*}/states"
+      additional_bindings {
+        get: "/v1/{name=projects/*/locations/*/registries/*/groups/*/devices/*}/states"
+      }
+    };
+  }
+
+  // Sets the access control policy on the specified resource. Replaces any
+  // existing policy.
+  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/locations/*/registries/*}:setIamPolicy"
+      body: "*"
+      additional_bindings {
+        post: "/v1/{resource=projects/*/locations/*/registries/*/groups/*}:setIamPolicy"
+        body: "*"
+      }
+    };
+  }
+
+  // Gets the access control policy for a resource.
+  // Returns an empty policy if the resource exists and does not have a policy
+  // set.
+  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/locations/*/registries/*}:getIamPolicy"
+      body: "*"
+      additional_bindings {
+        post: "/v1/{resource=projects/*/locations/*/registries/*/groups/*}:getIamPolicy"
+        body: "*"
+      }
+    };
+  }
+
+  // Returns permissions that a caller has on the specified resource.
+  // If the resource does not exist, this will return an empty set of
+  // permissions, not a NOT_FOUND error.
+  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/locations/*/registries/*}:testIamPermissions"
+      body: "*"
+      additional_bindings {
+        post: "/v1/{resource=projects/*/locations/*/registries/*/groups/*}:testIamPermissions"
+        body: "*"
+      }
+    };
+  }
+
+  // Sends a command to the specified device. In order for a device to be able
+  // to receive commands, it must:
+  // 1) be connected to Cloud IoT Core using the MQTT protocol, and
+  // 2) be subscribed to the group of MQTT topics specified by
+  //    /devices/{device-id}/commands/#. This subscription will receive commands
+  //    at the top-level topic /devices/{device-id}/commands as well as commands
+  //    for subfolders, like /devices/{device-id}/commands/subfolder.
+  //    Note that subscribing to specific subfolders is not supported.
+  // If the command could not be delivered to the device, this method will
+  // return an error; in particular, if the device is not subscribed, this
+  // method will return FAILED_PRECONDITION. Otherwise, this method will
+  // return OK. If the subscription is QoS 1, at least once delivery will be
+  // guaranteed; for QoS 0, no acknowledgment will be expected from the device.
+  rpc SendCommandToDevice(SendCommandToDeviceRequest) returns (SendCommandToDeviceResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/locations/*/registries/*/devices/*}:sendCommandToDevice"
+      body: "*"
+      additional_bindings {
+        post: "/v1/{name=projects/*/locations/*/registries/*/groups/*/devices/*}:sendCommandToDevice"
+        body: "*"
+      }
+    };
+  }
+
+  // Associates the device with the gateway.
+  rpc BindDeviceToGateway(BindDeviceToGatewayRequest) returns (BindDeviceToGatewayResponse) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/locations/*/registries/*}:bindDeviceToGateway"
+      body: "*"
+      additional_bindings {
+        post: "/v1/{parent=projects/*/locations/*/registries/*/groups/*}:bindDeviceToGateway"
+        body: "*"
+      }
+    };
+  }
+
+  // Deletes the association between the device and the gateway.
+  rpc UnbindDeviceFromGateway(UnbindDeviceFromGatewayRequest) returns (UnbindDeviceFromGatewayResponse) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/locations/*/registries/*}:unbindDeviceFromGateway"
+      body: "*"
+      additional_bindings {
+        post: "/v1/{parent=projects/*/locations/*/registries/*/groups/*}:unbindDeviceFromGateway"
+        body: "*"
+      }
+    };
+  }
+}
+
+// Request for `CreateDeviceRegistry`.
+message CreateDeviceRegistryRequest {
+  // The project and cloud region where this device registry must be created.
+  // For example, `projects/example-project/locations/us-central1`.
+  string parent = 1;
+
+  // The device registry. The field `name` must be empty. The server will
+  // generate that field from the device registry `id` provided and the
+  // `parent` field.
+  DeviceRegistry device_registry = 2;
+}
+
+// Request for `GetDeviceRegistry`.
+message GetDeviceRegistryRequest {
+  // The name of the device registry. For example,
+  // `projects/example-project/locations/us-central1/registries/my-registry`.
+  string name = 1;
+}
+
+// Request for `DeleteDeviceRegistry`.
+message DeleteDeviceRegistryRequest {
+  // The name of the device registry. For example,
+  // `projects/example-project/locations/us-central1/registries/my-registry`.
+  string name = 1;
+}
+
+// Request for `UpdateDeviceRegistry`.
+message UpdateDeviceRegistryRequest {
+  // The new values for the device registry. The `id` field must be empty, and
+  // the `name` field must indicate the path of the resource. For example,
+  // `projects/example-project/locations/us-central1/registries/my-registry`.
+  DeviceRegistry device_registry = 1;
+
+  // Only updates the `device_registry` fields indicated by this mask.
+  // The field mask must not be empty, and it must not contain fields that
+  // are immutable or only set by the server.
+  // Mutable top-level fields: `event_notification_config`, `http_config`,
+  // `mqtt_config`, and `state_notification_config`.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request for `ListDeviceRegistries`.
+message ListDeviceRegistriesRequest {
+  // The project and cloud region path. For example,
+  // `projects/example-project/locations/us-central1`.
+  string parent = 1;
+
+  // The maximum number of registries to return in the response. If this value
+  // is zero, the service will select a default size. A call may return fewer
+  // objects than requested. A non-empty `next_page_token` in the response
+  // indicates that more data is available.
+  int32 page_size = 2;
+
+  // The value returned by the last `ListDeviceRegistriesResponse`; indicates
+  // that this is a continuation of a prior `ListDeviceRegistries` call and
+  // the system should return the next page of data.
+  string page_token = 3;
+}
+
+// Response for `ListDeviceRegistries`.
+message ListDeviceRegistriesResponse {
+  // The registries that matched the query.
+  repeated DeviceRegistry device_registries = 1;
+
+  // If not empty, indicates that there may be more registries that match the
+  // request; this value should be passed in a new
+  // `ListDeviceRegistriesRequest`.
+  string next_page_token = 2;
+}
+
+// Request for `CreateDevice`.
+message CreateDeviceRequest {
+  // The name of the device registry where this device should be created.
+  // For example,
+  // `projects/example-project/locations/us-central1/registries/my-registry`.
+  string parent = 1;
+
+  // The device registration details. The field `name` must be empty. The server
+  // generates `name` from the device registry `id` and the
+  // `parent` field.
+  Device device = 2;
+}
+
+// Request for `GetDevice`.
+message GetDeviceRequest {
+  // The name of the device. For example,
+  // `projects/p0/locations/us-central1/registries/registry0/devices/device0` or
+  // `projects/p0/locations/us-central1/registries/registry0/devices/{num_id}`.
+  string name = 1;
+
+  // The fields of the `Device` resource to be returned in the response. If the
+  // field mask is unset or empty, all fields are returned.
+  google.protobuf.FieldMask field_mask = 2;
+}
+
+// Request for `UpdateDevice`.
+message UpdateDeviceRequest {
+  // The new values for the device. The `id` and `num_id` fields must
+  // be empty, and the field `name` must specify the name path. For example,
+  // `projects/p0/locations/us-central1/registries/registry0/devices/device0`or
+  // `projects/p0/locations/us-central1/registries/registry0/devices/{num_id}`.
+  Device device = 2;
+
+  // Only updates the `device` fields indicated by this mask.
+  // The field mask must not be empty, and it must not contain fields that
+  // are immutable or only set by the server.
+  // Mutable top-level fields: `credentials`, `blocked`, and `metadata`
+  google.protobuf.FieldMask update_mask = 3;
+}
+
+// Request for `DeleteDevice`.
+message DeleteDeviceRequest {
+  // The name of the device. For example,
+  // `projects/p0/locations/us-central1/registries/registry0/devices/device0` or
+  // `projects/p0/locations/us-central1/registries/registry0/devices/{num_id}`.
+  string name = 1;
+}
+
+// Request for `ListDevices`.
+message ListDevicesRequest {
+  // The device registry path. Required. For example,
+  // `projects/my-project/locations/us-central1/registries/my-registry`.
+  string parent = 1;
+
+  // A list of device numeric IDs. If empty, this field is ignored. Maximum
+  // IDs: 10,000.
+  repeated uint64 device_num_ids = 2;
+
+  // A list of device string IDs. For example, `['device0', 'device12']`.
+  // If empty, this field is ignored. Maximum IDs: 10,000
+  repeated string device_ids = 3;
+
+  // The fields of the `Device` resource to be returned in the response. The
+  // fields `id` and `num_id` are always returned, along with any
+  // other fields specified.
+  google.protobuf.FieldMask field_mask = 4;
+
+  // Options related to gateways.
+  GatewayListOptions gateway_list_options = 6;
+
+  // The maximum number of devices to return in the response. If this value
+  // is zero, the service will select a default size. A call may return fewer
+  // objects than requested. A non-empty `next_page_token` in the response
+  // indicates that more data is available.
+  int32 page_size = 100;
+
+  // The value returned by the last `ListDevicesResponse`; indicates
+  // that this is a continuation of a prior `ListDevices` call and
+  // the system should return the next page of data.
+  string page_token = 101;
+}
+
+// Options for limiting the list based on gateway type and associations.
+message GatewayListOptions {
+  // If not set, all devices and gateways are returned. If set, the list is
+  // filtered based on gateway type and associations.
+  oneof filter {
+    // If `GATEWAY` is specified, only gateways are returned. If `NON_GATEWAY`
+    // is specified, only non-gateway devices are returned. If
+    // `GATEWAY_TYPE_UNSPECIFIED` is specified, all devices are returned.
+    GatewayType gateway_type = 1;
+
+    // If set, only devices associated with the specified gateway are returned.
+    // The gateway ID can be numeric (`num_id`) or the user-defined string
+    // (`id`). For example, if `123` is specified, only devices bound to the
+    // gateway with `num_id` 123 are returned.
+    string associations_gateway_id = 2;
+
+    // If set, returns only the gateways with which the specified device is
+    // associated. The device ID can be numeric (`num_id`) or the user-defined
+    // string (`id`). For example, if `456` is specified, returns only the
+    // gateways to which the device with `num_id` 456 is bound.
+    string associations_device_id = 3;
+  }
+}
+
+// Response for `ListDevices`.
+message ListDevicesResponse {
+  // The devices that match the request.
+  repeated Device devices = 1;
+
+  // If not empty, indicates that there may be more devices that match the
+  // request; this value should be passed in a new `ListDevicesRequest`.
+  string next_page_token = 2;
+}
+
+// Request for `ModifyCloudToDeviceConfig`.
+message ModifyCloudToDeviceConfigRequest {
+  // The name of the device. For example,
+  // `projects/p0/locations/us-central1/registries/registry0/devices/device0` or
+  // `projects/p0/locations/us-central1/registries/registry0/devices/{num_id}`.
+  string name = 1;
+
+  // The version number to update. If this value is zero, it will not check the
+  // version number of the server and will always update the current version;
+  // otherwise, this update will fail if the version number found on the server
+  // does not match this version number. This is used to support multiple
+  // simultaneous updates without losing data.
+  int64 version_to_update = 2;
+
+  // The configuration data for the device.
+  bytes binary_data = 3;
+}
+
+// Request for `ListDeviceConfigVersions`.
+message ListDeviceConfigVersionsRequest {
+  // The name of the device. For example,
+  // `projects/p0/locations/us-central1/registries/registry0/devices/device0` or
+  // `projects/p0/locations/us-central1/registries/registry0/devices/{num_id}`.
+  string name = 1;
+
+  // The number of versions to list. Versions are listed in decreasing order of
+  // the version number. The maximum number of versions retained is 10. If this
+  // value is zero, it will return all the versions available.
+  int32 num_versions = 2;
+}
+
+// Response for `ListDeviceConfigVersions`.
+message ListDeviceConfigVersionsResponse {
+  // The device configuration for the last few versions. Versions are listed
+  // in decreasing order, starting from the most recent one.
+  repeated DeviceConfig device_configs = 1;
+}
+
+// Request for `ListDeviceStates`.
+message ListDeviceStatesRequest {
+  // The name of the device. For example,
+  // `projects/p0/locations/us-central1/registries/registry0/devices/device0` or
+  // `projects/p0/locations/us-central1/registries/registry0/devices/{num_id}`.
+  string name = 1;
+
+  // The number of states to list. States are listed in descending order of
+  // update time. The maximum number of states retained is 10. If this
+  // value is zero, it will return all the states available.
+  int32 num_states = 2;
+}
+
+// Response for `ListDeviceStates`.
+message ListDeviceStatesResponse {
+  // The last few device states. States are listed in descending order of server
+  // update time, starting from the most recent one.
+  repeated DeviceState device_states = 1;
+}
+
+// Request for `SendCommandToDevice`.
+message SendCommandToDeviceRequest {
+  // The name of the device. For example,
+  // `projects/p0/locations/us-central1/registries/registry0/devices/device0` or
+  // `projects/p0/locations/us-central1/registries/registry0/devices/{num_id}`.
+  string name = 1;
+
+  // The command data to send to the device.
+  bytes binary_data = 2;
+
+  // Optional subfolder for the command. If empty, the command will be delivered
+  // to the /devices/{device-id}/commands topic, otherwise it will be delivered
+  // to the /devices/{device-id}/commands/{subfolder} topic. Multi-level
+  // subfolders are allowed. This field must not have more than 256 characters,
+  // and must not contain any MQTT wildcards ("+" or "#") or null characters.
+  string subfolder = 3;
+}
+
+// Response for `SendCommandToDevice`.
+message SendCommandToDeviceResponse {
+
+}
+
+// Request for `BindDeviceToGateway`.
+message BindDeviceToGatewayRequest {
+  // The name of the registry. For example,
+  // `projects/example-project/locations/us-central1/registries/my-registry`.
+  string parent = 1;
+
+  // The value of `gateway_id` can be either the device numeric ID or the
+  // user-defined device identifier.
+  string gateway_id = 2;
+
+  // The device to associate with the specified gateway. The value of
+  // `device_id` can be either the device numeric ID or the user-defined device
+  // identifier.
+  string device_id = 3;
+}
+
+// Response for `BindDeviceToGateway`.
+message BindDeviceToGatewayResponse {
+
+}
+
+// Request for `UnbindDeviceFromGateway`.
+message UnbindDeviceFromGatewayRequest {
+  // The name of the registry. For example,
+  // `projects/example-project/locations/us-central1/registries/my-registry`.
+  string parent = 1;
+
+  // The value of `gateway_id` can be either the device numeric ID or the
+  // user-defined device identifier.
+  string gateway_id = 2;
+
+  // The device to disassociate from the specified gateway. The value of
+  // `device_id` can be either the device numeric ID or the user-defined device
+  // identifier.
+  string device_id = 3;
+}
+
+// Response for `UnbindDeviceFromGateway`.
+message UnbindDeviceFromGatewayResponse {
+
+}
diff --git a/iot/google/cloud/iot_v1/proto/resources.proto b/iot/google/cloud/iot_v1/proto/resources.proto
new file mode 100644
index 000000000000..a362ca26b391
--- /dev/null
+++ b/iot/google/cloud/iot_v1/proto/resources.proto
@@ -0,0 +1,475 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.iot.v1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/iot/v1;iot";
+option java_multiple_files = true;
+option java_outer_classname = "ResourcesProto";
+option java_package = "com.google.cloud.iot.v1";
+
+
+// The device resource.
+message Device {
+  // The user-defined device identifier. The device ID must be unique
+  // within a device registry.
+  string id = 1;
+
+  // The resource path name. For example,
+  // `projects/p1/locations/us-central1/registries/registry0/devices/dev0` or
+  // `projects/p1/locations/us-central1/registries/registry0/devices/{num_id}`.
+  // When `name` is populated as a response from the service, it always ends
+  // in the device numeric ID.
+  string name = 2;
+
+  // [Output only] A server-defined unique numeric ID for the device. This is a
+  // more compact way to identify devices, and it is globally unique.
+  uint64 num_id = 3;
+
+  // The credentials used to authenticate this device. To allow credential
+  // rotation without interruption, multiple device credentials can be bound to
+  // this device. No more than 3 credentials can be bound to a single device at
+  // a time. When new credentials are added to a device, they are verified
+  // against the registry credentials. For details, see the description of the
+  // `DeviceRegistry.credentials` field.
+  repeated DeviceCredential credentials = 12;
+
+  // [Output only] The last time an MQTT `PINGREQ` was received. This field
+  // applies only to devices connecting through MQTT. MQTT clients usually only
+  // send `PINGREQ` messages if the connection is idle, and no other messages
+  // have been sent. Timestamps are periodically collected and written to
+  // storage; they may be stale by a few minutes.
+  google.protobuf.Timestamp last_heartbeat_time = 7;
+
+  // [Output only] The last time a telemetry event was received. Timestamps are
+  // periodically collected and written to storage; they may be stale by a few
+  // minutes.
+  google.protobuf.Timestamp last_event_time = 8;
+
+  // [Output only] The last time a state event was received. Timestamps are
+  // periodically collected and written to storage; they may be stale by a few
+  // minutes.
+  google.protobuf.Timestamp last_state_time = 20;
+
+  // [Output only] The last time a cloud-to-device config version acknowledgment
+  // was received from the device. This field is only for configurations
+  // sent through MQTT.
+  google.protobuf.Timestamp last_config_ack_time = 14;
+
+  // [Output only] The last time a cloud-to-device config version was sent to
+  // the device.
+  google.protobuf.Timestamp last_config_send_time = 18;
+
+  // If a device is blocked, connections or requests from this device will fail.
+  // Can be used to temporarily prevent the device from connecting if, for
+  // example, the sensor is generating bad data and needs maintenance.
+  bool blocked = 19;
+
+  // [Output only] The time the most recent error occurred, such as a failure to
+  // publish to Cloud Pub/Sub. This field is the timestamp of
+  // 'last_error_status'.
+  google.protobuf.Timestamp last_error_time = 10;
+
+  // [Output only] The error message of the most recent error, such as a failure
+  // to publish to Cloud Pub/Sub. 'last_error_time' is the timestamp of this
+  // field. If no errors have occurred, this field has an empty message
+  // and the status code 0 == OK. Otherwise, this field is expected to have a
+  // status code other than OK.
+  google.rpc.Status last_error_status = 11;
+
+  // The most recent device configuration, which is eventually sent from
+  // Cloud IoT Core to the device. If not present on creation, the
+  // configuration will be initialized with an empty payload and version value
+  // of `1`. To update this field after creation, use the
+  // `DeviceManager.ModifyCloudToDeviceConfig` method.
+  DeviceConfig config = 13;
+
+  // [Output only] The state most recently received from the device. If no state
+  // has been reported, this field is not present.
+  DeviceState state = 16;
+
+  // **Beta Feature**
+  //
+  // The logging verbosity for device activity. If unspecified,
+  // DeviceRegistry.log_level will be used.
+  LogLevel log_level = 21;
+
+  // The metadata key-value pairs assigned to the device. This metadata is not
+  // interpreted or indexed by Cloud IoT Core. It can be used to add contextual
+  // information for the device.
+  //
+  // Keys must conform to the regular expression [a-zA-Z][a-zA-Z0-9-_.+~%]+ and
+  // be less than 128 bytes in length.
+  //
+  // Values are free-form strings. Each value must be less than or equal to 32
+  // KB in size.
+  //
+  // The total size of all keys and values must be less than 256 KB, and the
+  // maximum number of key-value pairs is 500.
+  map<string, string> metadata = 17;
+
+  // Gateway-related configuration and state.
+  GatewayConfig gateway_config = 24;
+}
+
+// Gateway-related configuration and state.
+message GatewayConfig {
+  // Indicates whether the device is a gateway.
+  GatewayType gateway_type = 1;
+
+  // Indicates how to authorize and/or authenticate devices to access the
+  // gateway.
+  GatewayAuthMethod gateway_auth_method = 2;
+
+  // [Output only] The ID of the gateway the device accessed most recently.
+  string last_accessed_gateway_id = 3;
+
+  // [Output only] The most recent time at which the device accessed the gateway
+  // specified in `last_accessed_gateway`.
+  google.protobuf.Timestamp last_accessed_gateway_time = 4;
+}
+
+// A container for a group of devices.
+message DeviceRegistry {
+  // The identifier of this device registry. For example, `myRegistry`.
+  string id = 1;
+
+  // The resource path name. For example,
+  // `projects/example-project/locations/us-central1/registries/my-registry`.
+  string name = 2;
+
+  // The configuration for notification of telemetry events received from the
+  // device. All telemetry events that were successfully published by the
+  // device and acknowledged by Cloud IoT Core are guaranteed to be
+  // delivered to Cloud Pub/Sub. If multiple configurations match a message,
+  // only the first matching configuration is used. If you try to publish a
+  // device telemetry event using MQTT without specifying a Cloud Pub/Sub topic
+  // for the device's registry, the connection closes automatically. If you try
+  // to do so using an HTTP connection, an error is returned. Up to 10
+  // configurations may be provided.
+  repeated EventNotificationConfig event_notification_configs = 10;
+
+  // The configuration for notification of new states received from the device.
+  // State updates are guaranteed to be stored in the state history, but
+  // notifications to Cloud Pub/Sub are not guaranteed. For example, if
+  // permissions are misconfigured or the specified topic doesn't exist, no
+  // notification will be published but the state will still be stored in Cloud
+  // IoT Core.
+  StateNotificationConfig state_notification_config = 7;
+
+  // The MQTT configuration for this device registry.
+  MqttConfig mqtt_config = 4;
+
+  // The DeviceService (HTTP) configuration for this device registry.
+  HttpConfig http_config = 9;
+
+  // **Beta Feature**
+  //
+  // The default logging verbosity for activity from devices in this registry.
+  // The verbosity level can be overridden by Device.log_level.
+  LogLevel log_level = 11;
+
+  // The credentials used to verify the device credentials. No more than 10
+  // credentials can be bound to a single registry at a time. The verification
+  // process occurs at the time of device creation or update. If this field is
+  // empty, no verification is performed. Otherwise, the credentials of a newly
+  // created device or added credentials of an updated device should be signed
+  // with one of these registry credentials.
+  //
+  // Note, however, that existing devices will never be affected by
+  // modifications to this list of credentials: after a device has been
+  // successfully created in a registry, it should be able to connect even if
+  // its registry credentials are revoked, deleted, or modified.
+  repeated RegistryCredential credentials = 8;
+}
+
+// The configuration of MQTT for a device registry.
+message MqttConfig {
+  // If enabled, allows connections using the MQTT protocol. Otherwise, MQTT
+  // connections to this registry will fail.
+  MqttState mqtt_enabled_state = 1;
+}
+
+// The configuration of the HTTP bridge for a device registry.
+message HttpConfig {
+  // If enabled, allows devices to use DeviceService via the HTTP protocol.
+  // Otherwise, any requests to DeviceService will fail for this registry.
+  HttpState http_enabled_state = 1;
+}
+
+// The configuration for forwarding telemetry events.
+message EventNotificationConfig {
+  // If the subfolder name matches this string exactly, this configuration will
+  // be used. The string must not include the leading '/' character. If empty,
+  // all strings are matched. This field is used only for telemetry events;
+  // subfolders are not supported for state changes.
+  string subfolder_matches = 2;
+
+  // A Cloud Pub/Sub topic name. For example,
+  // `projects/myProject/topics/deviceEvents`.
+  string pubsub_topic_name = 1;
+}
+
+// The configuration for notification of new states received from the device.
+message StateNotificationConfig {
+  // A Cloud Pub/Sub topic name. For example,
+  // `projects/myProject/topics/deviceEvents`.
+  string pubsub_topic_name = 1;
+}
+
+// A server-stored registry credential used to validate device credentials.
+message RegistryCredential {
+  // The credential data. Reserved for expansion in the future.
+  oneof credential {
+    // A public key certificate used to verify the device credentials.
+    PublicKeyCertificate public_key_certificate = 1;
+  }
+}
+
+// Details of an X.509 certificate. For informational purposes only.
+message X509CertificateDetails {
+  // The entity that signed the certificate.
+  string issuer = 1;
+
+  // The entity the certificate and public key belong to.
+  string subject = 2;
+
+  // The time the certificate becomes valid.
+  google.protobuf.Timestamp start_time = 3;
+
+  // The time the certificate becomes invalid.
+  google.protobuf.Timestamp expiry_time = 4;
+
+  // The algorithm used to sign the certificate.
+  string signature_algorithm = 5;
+
+  // The type of public key in the certificate.
+  string public_key_type = 6;
+}
+
+// A public key certificate format and data.
+message PublicKeyCertificate {
+  // The certificate format.
+  PublicKeyCertificateFormat format = 1;
+
+  // The certificate data.
+  string certificate = 2;
+
+  // [Output only] The certificate details. Used only for X.509 certificates.
+  X509CertificateDetails x509_details = 3;
+}
+
+// A server-stored device credential used for authentication.
+message DeviceCredential {
+  // The credential data. Reserved for expansion in the future.
+  oneof credential {
+    // A public key used to verify the signature of JSON Web Tokens (JWTs).
+    // When adding a new device credential, either via device creation or via
+    // modifications, this public key credential may be required to be signed by
+    // one of the registry level certificates. More specifically, if the
+    // registry contains at least one certificate, any new device credential
+    // must be signed by one of the registry certificates. As a result,
+    // when the registry contains certificates, only X.509 certificates are
+    // accepted as device credentials. However, if the registry does
+    // not contain a certificate, self-signed certificates and public keys will
+    // be accepted. New device credentials must be different from every
+    // registry-level certificate.
+    PublicKeyCredential public_key = 2;
+  }
+
+  // [Optional] The time at which this credential becomes invalid. This
+  // credential will be ignored for new client authentication requests after
+  // this timestamp; however, it will not be automatically deleted.
+  google.protobuf.Timestamp expiration_time = 6;
+}
+
+// A public key format and data.
+message PublicKeyCredential {
+  // The format of the key.
+  PublicKeyFormat format = 1;
+
+  // The key data.
+  string key = 2;
+}
+
+// The device configuration. Eventually delivered to devices.
+message DeviceConfig {
+  // [Output only] The version of this update. The version number is assigned by
+  // the server, and is always greater than 0 after device creation. The
+  // version must be 0 on the `CreateDevice` request if a `config` is
+  // specified; the response of `CreateDevice` will always have a value of 1.
+  int64 version = 1;
+
+  // [Output only] The time at which this configuration version was updated in
+  // Cloud IoT Core. This timestamp is set by the server.
+  google.protobuf.Timestamp cloud_update_time = 2;
+
+  // [Output only] The time at which Cloud IoT Core received the
+  // acknowledgment from the device, indicating that the device has received
+  // this configuration version. If this field is not present, the device has
+  // not yet acknowledged that it received this version. Note that when
+  // the config was sent to the device, many config versions may have been
+  // available in Cloud IoT Core while the device was disconnected, and on
+  // connection, only the latest version is sent to the device. Some
+  // versions may never be sent to the device, and therefore are never
+  // acknowledged. This timestamp is set by Cloud IoT Core.
+  google.protobuf.Timestamp device_ack_time = 3;
+
+  // The device configuration data.
+  bytes binary_data = 4;
+}
+
+// The device state, as reported by the device.
+message DeviceState {
+  // [Output only] The time at which this state version was updated in Cloud
+  // IoT Core.
+  google.protobuf.Timestamp update_time = 1;
+
+  // The device state data.
+  bytes binary_data = 2;
+}
+
+// Indicates whether an MQTT connection is enabled or disabled. See the field
+// description for details.
+enum MqttState {
+  // No MQTT state specified. If not specified, MQTT will be enabled by default.
+  MQTT_STATE_UNSPECIFIED = 0;
+
+  // Enables a MQTT connection.
+  MQTT_ENABLED = 1;
+
+  // Disables a MQTT connection.
+  MQTT_DISABLED = 2;
+}
+
+// Indicates whether DeviceService (HTTP) is enabled or disabled for the
+// registry. See the field description for details.
+enum HttpState {
+  // No HTTP state specified. If not specified, DeviceService will be
+  // enabled by default.
+  HTTP_STATE_UNSPECIFIED = 0;
+
+  // Enables DeviceService (HTTP) service for the registry.
+  HTTP_ENABLED = 1;
+
+  // Disables DeviceService (HTTP) service for the registry.
+  HTTP_DISABLED = 2;
+}
+
+// **Beta Feature**
+//
+// The logging verbosity for device activity. Specifies which events should be
+// written to logs. For example, if the LogLevel is ERROR, only events that
+// terminate in errors will be logged. LogLevel is inclusive; enabling INFO
+// logging will also enable ERROR logging.
+enum LogLevel {
+  // No logging specified. If not specified, logging will be disabled.
+  LOG_LEVEL_UNSPECIFIED = 0;
+
+  // Disables logging.
+  NONE = 10;
+
+  // Error events will be logged.
+  ERROR = 20;
+
+  // Informational events will be logged, such as connections and
+  // disconnections.
+  INFO = 30;
+
+  // All events will be logged.
+  DEBUG = 40;
+}
+
+// Gateway type.
+enum GatewayType {
+  // If unspecified, the device is considered a non-gateway device.
+  GATEWAY_TYPE_UNSPECIFIED = 0;
+
+  // The device is a gateway.
+  GATEWAY = 1;
+
+  // The device is not a gateway.
+  NON_GATEWAY = 2;
+}
+
+// The gateway authorization/authentication method. This setting determines how
+// Cloud IoT Core authorizes/authenticate devices to access the gateway.
+enum GatewayAuthMethod {
+  // No authentication/authorization method specified. No devices are allowed to
+  // access the gateway.
+  GATEWAY_AUTH_METHOD_UNSPECIFIED = 0;
+
+  // The device is authenticated through the gateway association only. Device
+  // credentials are ignored even if provided.
+  ASSOCIATION_ONLY = 1;
+
+  // The device is authenticated through its own credentials. Gateway
+  // association is not checked.
+  DEVICE_AUTH_TOKEN_ONLY = 2;
+
+  // The device is authenticated through both device credentials and gateway
+  // association. The device must be bound to the gateway and must provide its
+  // own credentials.
+  ASSOCIATION_AND_DEVICE_AUTH_TOKEN = 3;
+}
+
+// The supported formats for the public key.
+enum PublicKeyCertificateFormat {
+  // The format has not been specified. This is an invalid default value and
+  // must not be used.
+  UNSPECIFIED_PUBLIC_KEY_CERTIFICATE_FORMAT = 0;
+
+  // An X.509v3 certificate ([RFC5280](https://www.ietf.org/rfc/rfc5280.txt)),
+  // encoded in base64, and wrapped by `-----BEGIN CERTIFICATE-----` and
+  // `-----END CERTIFICATE-----`.
+  X509_CERTIFICATE_PEM = 1;
+}
+
+// The supported formats for the public key.
+enum PublicKeyFormat {
+  // The format has not been specified. This is an invalid default value and
+  // must not be used.
+  UNSPECIFIED_PUBLIC_KEY_FORMAT = 0;
+
+  // An RSA public key encoded in base64, and wrapped by
+  // `-----BEGIN PUBLIC KEY-----` and `-----END PUBLIC KEY-----`. This can be
+  // used to verify `RS256` signatures in JWT tokens ([RFC7518](
+  // https://www.ietf.org/rfc/rfc7518.txt)).
+  RSA_PEM = 3;
+
+  // As RSA_PEM, but wrapped in an X.509v3 certificate ([RFC5280](
+  // https://www.ietf.org/rfc/rfc5280.txt)), encoded in base64, and wrapped by
+  // `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`.
+  RSA_X509_PEM = 1;
+
+  // Public key for the ECDSA algorithm using P-256 and SHA-256, encoded in
+  // base64, and wrapped by `-----BEGIN PUBLIC KEY-----` and `-----END
+  // PUBLIC KEY-----`. This can be used to verify JWT tokens with the `ES256`
+  // algorithm ([RFC7518](https://www.ietf.org/rfc/rfc7518.txt)). This curve is
+  // defined in [OpenSSL](https://www.openssl.org/) as the `prime256v1` curve.
+  ES256_PEM = 2;
+
+  // As ES256_PEM, but wrapped in an X.509v3 certificate ([RFC5280](
+  // https://www.ietf.org/rfc/rfc5280.txt)), encoded in base64, and wrapped by
+  // `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`.
+  ES256_X509_PEM = 4;
+}
diff --git a/iot/synth.metadata b/iot/synth.metadata
index cba5c9ec6c0d..2836a40a9fed 100644
--- a/iot/synth.metadata
+++ b/iot/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:20:11.894857Z",
+  "updateTime": "2019-01-24T00:44:58.047062Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/iot/synth.py b/iot/synth.py
index 315caa1bfc7e..2f9304a3e43c 100644
--- a/iot/synth.py
+++ b/iot/synth.py
@@ -27,6 +27,7 @@
     "v1",
     config_path="/google/cloud/iot/artman_cloudiot.yaml",
     artman_output_name="iot-v1",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/iot_v1")
diff --git a/kms/google/cloud/kms_v1/proto/resources.proto b/kms/google/cloud/kms_v1/proto/resources.proto
new file mode 100644
index 000000000000..0bd39ef2678c
--- /dev/null
+++ b/kms/google/cloud/kms_v1/proto/resources.proto
@@ -0,0 +1,359 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.kms.v1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+option cc_enable_arenas = true;
+option csharp_namespace = "Google.Cloud.Kms.V1";
+option go_package = "google.golang.org/genproto/googleapis/cloud/kms/v1;kms";
+option java_multiple_files = true;
+option java_outer_classname = "KmsResourcesProto";
+option java_package = "com.google.cloud.kms.v1";
+option php_namespace = "Google\\Cloud\\Kms\\V1";
+
+
+// A [KeyRing][google.cloud.kms.v1.KeyRing] is a toplevel logical grouping of [CryptoKeys][google.cloud.kms.v1.CryptoKey].
+message KeyRing {
+  // Output only. The resource name for the [KeyRing][google.cloud.kms.v1.KeyRing] in the format
+  // `projects/*/locations/*/keyRings/*`.
+  string name = 1;
+
+  // Output only. The time at which this [KeyRing][google.cloud.kms.v1.KeyRing] was created.
+  google.protobuf.Timestamp create_time = 2;
+}
+
+// A [CryptoKey][google.cloud.kms.v1.CryptoKey] represents a logical key that can be used for cryptographic
+// operations.
+//
+// A [CryptoKey][google.cloud.kms.v1.CryptoKey] is made up of one or more [versions][google.cloud.kms.v1.CryptoKeyVersion], which
+// represent the actual key material used in cryptographic operations.
+message CryptoKey {
+  // [CryptoKeyPurpose][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose] describes the cryptographic capabilities of a
+  // [CryptoKey][google.cloud.kms.v1.CryptoKey]. A given key can only be used for the operations allowed by
+  // its purpose.
+  enum CryptoKeyPurpose {
+    // Not specified.
+    CRYPTO_KEY_PURPOSE_UNSPECIFIED = 0;
+
+    // [CryptoKeys][google.cloud.kms.v1.CryptoKey] with this purpose may be used with
+    // [Encrypt][google.cloud.kms.v1.KeyManagementService.Encrypt] and
+    // [Decrypt][google.cloud.kms.v1.KeyManagementService.Decrypt].
+    ENCRYPT_DECRYPT = 1;
+
+    // [CryptoKeys][google.cloud.kms.v1.CryptoKey] with this purpose may be used with
+    // [AsymmetricSign][google.cloud.kms.v1.KeyManagementService.AsymmetricSign] and
+    // [GetPublicKey][google.cloud.kms.v1.KeyManagementService.GetPublicKey].
+    ASYMMETRIC_SIGN = 5;
+
+    // [CryptoKeys][google.cloud.kms.v1.CryptoKey] with this purpose may be used with
+    // [AsymmetricDecrypt][google.cloud.kms.v1.KeyManagementService.AsymmetricDecrypt] and
+    // [GetPublicKey][google.cloud.kms.v1.KeyManagementService.GetPublicKey].
+    ASYMMETRIC_DECRYPT = 6;
+  }
+
+  // Output only. The resource name for this [CryptoKey][google.cloud.kms.v1.CryptoKey] in the format
+  // `projects/*/locations/*/keyRings/*/cryptoKeys/*`.
+  string name = 1;
+
+  // Output only. A copy of the "primary" [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] that will be used
+  // by [Encrypt][google.cloud.kms.v1.KeyManagementService.Encrypt] when this [CryptoKey][google.cloud.kms.v1.CryptoKey] is given
+  // in [EncryptRequest.name][google.cloud.kms.v1.EncryptRequest.name].
+  //
+  // The [CryptoKey][google.cloud.kms.v1.CryptoKey]'s primary version can be updated via
+  // [UpdateCryptoKeyPrimaryVersion][google.cloud.kms.v1.KeyManagementService.UpdateCryptoKeyPrimaryVersion].
+  //
+  // All keys with [purpose][google.cloud.kms.v1.CryptoKey.purpose]
+  // [ENCRYPT_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT] have a
+  // primary. For other keys, this field will be omitted.
+  CryptoKeyVersion primary = 2;
+
+  // The immutable purpose of this [CryptoKey][google.cloud.kms.v1.CryptoKey].
+  CryptoKeyPurpose purpose = 3;
+
+  // Output only. The time at which this [CryptoKey][google.cloud.kms.v1.CryptoKey] was created.
+  google.protobuf.Timestamp create_time = 5;
+
+  // At [next_rotation_time][google.cloud.kms.v1.CryptoKey.next_rotation_time], the Key Management Service will automatically:
+  //
+  // 1. Create a new version of this [CryptoKey][google.cloud.kms.v1.CryptoKey].
+  // 2. Mark the new version as primary.
+  //
+  // Key rotations performed manually via
+  // [CreateCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.CreateCryptoKeyVersion] and
+  // [UpdateCryptoKeyPrimaryVersion][google.cloud.kms.v1.KeyManagementService.UpdateCryptoKeyPrimaryVersion]
+  // do not affect [next_rotation_time][google.cloud.kms.v1.CryptoKey.next_rotation_time].
+  //
+  // Keys with [purpose][google.cloud.kms.v1.CryptoKey.purpose]
+  // [ENCRYPT_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT] support
+  // automatic rotation. For other keys, this field must be omitted.
+  google.protobuf.Timestamp next_rotation_time = 7;
+
+  // Controls the rate of automatic rotation.
+  oneof rotation_schedule {
+    // [next_rotation_time][google.cloud.kms.v1.CryptoKey.next_rotation_time] will be advanced by this period when the service
+    // automatically rotates a key. Must be at least one day.
+    //
+    // If [rotation_period][google.cloud.kms.v1.CryptoKey.rotation_period] is set, [next_rotation_time][google.cloud.kms.v1.CryptoKey.next_rotation_time] must also be set.
+    //
+    // Keys with [purpose][google.cloud.kms.v1.CryptoKey.purpose]
+    // [ENCRYPT_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT] support
+    // automatic rotation. For other keys, this field must be omitted.
+    google.protobuf.Duration rotation_period = 8;
+  }
+
+  // A template describing settings for new [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] instances.
+  // The properties of new [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] instances created by either
+  // [CreateCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.CreateCryptoKeyVersion] or
+  // auto-rotation are controlled by this template.
+  CryptoKeyVersionTemplate version_template = 11;
+
+  // Labels with user-defined metadata. For more information, see
+  // [Labeling Keys](/kms/docs/labeling-keys).
+  map<string, string> labels = 10;
+}
+
+// A [CryptoKeyVersionTemplate][google.cloud.kms.v1.CryptoKeyVersionTemplate] specifies the properties to use when creating
+// a new [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion], either manually with
+// [CreateCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.CreateCryptoKeyVersion] or
+// automatically as a result of auto-rotation.
+message CryptoKeyVersionTemplate {
+  // [ProtectionLevel][google.cloud.kms.v1.ProtectionLevel] to use when creating a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] based on
+  // this template. Immutable. Defaults to [SOFTWARE][google.cloud.kms.v1.ProtectionLevel.SOFTWARE].
+  ProtectionLevel protection_level = 1;
+
+  // Required. [Algorithm][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionAlgorithm] to use
+  // when creating a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] based on this template.
+  //
+  // For backwards compatibility, GOOGLE_SYMMETRIC_ENCRYPTION is implied if both
+  // this field is omitted and [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] is
+  // [ENCRYPT_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT].
+  CryptoKeyVersion.CryptoKeyVersionAlgorithm algorithm = 3;
+}
+
+// Contains an HSM-generated attestation about a key operation.
+message KeyOperationAttestation {
+  // Attestion formats provided by the HSM.
+  enum AttestationFormat {
+    ATTESTATION_FORMAT_UNSPECIFIED = 0;
+
+    // Cavium HSM attestation compressed with gzip. Note that this format is
+    // defined by Cavium and subject to change at any time.
+    CAVIUM_V1_COMPRESSED = 3;
+  }
+
+  // Output only. The format of the attestation data.
+  AttestationFormat format = 4;
+
+  // Output only. The attestation data provided by the HSM when the key
+  // operation was performed.
+  bytes content = 5;
+}
+
+// A [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] represents an individual cryptographic key, and the
+// associated key material.
+//
+// An [ENABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.ENABLED] version can be
+// used for cryptographic operations.
+//
+// For security reasons, the raw cryptographic key material represented by a
+// [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] can never be viewed or exported. It can only be used to
+// encrypt, decrypt, or sign data when an authorized user or application invokes
+// Cloud KMS.
+message CryptoKeyVersion {
+  // The algorithm of the [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion], indicating what
+  // parameters must be used for each cryptographic operation.
+  //
+  // The
+  // [GOOGLE_SYMMETRIC_ENCRYPTION][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION]
+  // algorithm is usable with [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose]
+  // [ENCRYPT_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT].
+  //
+  // Algorithms beginning with "RSA_SIGN_" are usable with [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose]
+  // [ASYMMETRIC_SIGN][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_SIGN].
+  //
+  // The fields in the name after "RSA_SIGN_" correspond to the following
+  // parameters: padding algorithm, modulus bit length, and digest algorithm.
+  //
+  // For PSS, the salt length used is equal to the length of digest
+  // algorithm. For example,
+  // [RSA_SIGN_PSS_2048_SHA256][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionAlgorithm.RSA_SIGN_PSS_2048_SHA256]
+  // will use PSS with a salt length of 256 bits or 32 bytes.
+  //
+  // Algorithms beginning with "RSA_DECRYPT_" are usable with
+  // [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose]
+  // [ASYMMETRIC_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_DECRYPT].
+  //
+  // The fields in the name after "RSA_DECRYPT_" correspond to the following
+  // parameters: padding algorithm, modulus bit length, and digest algorithm.
+  //
+  // Algorithms beginning with "EC_SIGN_" are usable with [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose]
+  // [ASYMMETRIC_SIGN][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_SIGN].
+  //
+  // The fields in the name after "EC_SIGN_" correspond to the following
+  // parameters: elliptic curve, digest algorithm.
+  enum CryptoKeyVersionAlgorithm {
+    // Not specified.
+    CRYPTO_KEY_VERSION_ALGORITHM_UNSPECIFIED = 0;
+
+    // Creates symmetric encryption keys.
+    GOOGLE_SYMMETRIC_ENCRYPTION = 1;
+
+    // RSASSA-PSS 2048 bit key with a SHA256 digest.
+    RSA_SIGN_PSS_2048_SHA256 = 2;
+
+    // RSASSA-PSS 3072 bit key with a SHA256 digest.
+    RSA_SIGN_PSS_3072_SHA256 = 3;
+
+    // RSASSA-PSS 4096 bit key with a SHA256 digest.
+    RSA_SIGN_PSS_4096_SHA256 = 4;
+
+    // RSASSA-PKCS1-v1_5 with a 2048 bit key and a SHA256 digest.
+    RSA_SIGN_PKCS1_2048_SHA256 = 5;
+
+    // RSASSA-PKCS1-v1_5 with a 3072 bit key and a SHA256 digest.
+    RSA_SIGN_PKCS1_3072_SHA256 = 6;
+
+    // RSASSA-PKCS1-v1_5 with a 4096 bit key and a SHA256 digest.
+    RSA_SIGN_PKCS1_4096_SHA256 = 7;
+
+    // RSAES-OAEP 2048 bit key with a SHA256 digest.
+    RSA_DECRYPT_OAEP_2048_SHA256 = 8;
+
+    // RSAES-OAEP 3072 bit key with a SHA256 digest.
+    RSA_DECRYPT_OAEP_3072_SHA256 = 9;
+
+    // RSAES-OAEP 4096 bit key with a SHA256 digest.
+    RSA_DECRYPT_OAEP_4096_SHA256 = 10;
+
+    // ECDSA on the NIST P-256 curve with a SHA256 digest.
+    EC_SIGN_P256_SHA256 = 12;
+
+    // ECDSA on the NIST P-384 curve with a SHA384 digest.
+    EC_SIGN_P384_SHA384 = 13;
+  }
+
+  // The state of a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion], indicating if it can be used.
+  enum CryptoKeyVersionState {
+    // Not specified.
+    CRYPTO_KEY_VERSION_STATE_UNSPECIFIED = 0;
+
+    // This version is still being generated. It may not be used, enabled,
+    // disabled, or destroyed yet. Cloud KMS will automatically mark this
+    // version [ENABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.ENABLED] as soon as the version is ready.
+    PENDING_GENERATION = 5;
+
+    // This version may be used for cryptographic operations.
+    ENABLED = 1;
+
+    // This version may not be used, but the key material is still available,
+    // and the version can be placed back into the [ENABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.ENABLED] state.
+    DISABLED = 2;
+
+    // This version is destroyed, and the key material is no longer stored.
+    // A version may not leave this state once entered.
+    DESTROYED = 3;
+
+    // This version is scheduled for destruction, and will be destroyed soon.
+    // Call
+    // [RestoreCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.RestoreCryptoKeyVersion]
+    // to put it back into the [DISABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DISABLED] state.
+    DESTROY_SCHEDULED = 4;
+  }
+
+  // A view for [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]s. Controls the level of detail returned
+  // for [CryptoKeyVersions][google.cloud.kms.v1.CryptoKeyVersion] in
+  // [KeyManagementService.ListCryptoKeyVersions][google.cloud.kms.v1.KeyManagementService.ListCryptoKeyVersions] and
+  // [KeyManagementService.ListCryptoKeys][google.cloud.kms.v1.KeyManagementService.ListCryptoKeys].
+  enum CryptoKeyVersionView {
+    // Default view for each [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]. Does not include
+    // the [attestation][google.cloud.kms.v1.CryptoKeyVersion.attestation] field.
+    CRYPTO_KEY_VERSION_VIEW_UNSPECIFIED = 0;
+
+    // Provides all fields in each [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion], including the
+    // [attestation][google.cloud.kms.v1.CryptoKeyVersion.attestation].
+    FULL = 1;
+  }
+
+  // Output only. The resource name for this [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] in the format
+  // `projects/*/locations/*/keyRings/*/cryptoKeys/*/cryptoKeyVersions/*`.
+  string name = 1;
+
+  // The current state of the [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion].
+  CryptoKeyVersionState state = 3;
+
+  // Output only. The [ProtectionLevel][google.cloud.kms.v1.ProtectionLevel] describing how crypto operations are
+  // performed with this [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion].
+  ProtectionLevel protection_level = 7;
+
+  // Output only. The [CryptoKeyVersionAlgorithm][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionAlgorithm] that this
+  // [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] supports.
+  CryptoKeyVersionAlgorithm algorithm = 10;
+
+  // Output only. Statement that was generated and signed by the HSM at key
+  // creation time. Use this statement to verify attributes of the key as stored
+  // on the HSM, independently of Google. Only provided for key versions with
+  // [protection_level][google.cloud.kms.v1.CryptoKeyVersion.protection_level] [HSM][google.cloud.kms.v1.ProtectionLevel.HSM].
+  KeyOperationAttestation attestation = 8;
+
+  // Output only. The time at which this [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] was created.
+  google.protobuf.Timestamp create_time = 4;
+
+  // Output only. The time this [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]'s key material was
+  // generated.
+  google.protobuf.Timestamp generate_time = 11;
+
+  // Output only. The time this [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]'s key material is scheduled
+  // for destruction. Only present if [state][google.cloud.kms.v1.CryptoKeyVersion.state] is
+  // [DESTROY_SCHEDULED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DESTROY_SCHEDULED].
+  google.protobuf.Timestamp destroy_time = 5;
+
+  // Output only. The time this CryptoKeyVersion's key material was
+  // destroyed. Only present if [state][google.cloud.kms.v1.CryptoKeyVersion.state] is
+  // [DESTROYED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DESTROYED].
+  google.protobuf.Timestamp destroy_event_time = 6;
+}
+
+// The public key for a given [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]. Obtained via
+// [GetPublicKey][google.cloud.kms.v1.KeyManagementService.GetPublicKey].
+message PublicKey {
+  // The public key, encoded in PEM format. For more information, see the
+  // [RFC 7468](https://tools.ietf.org/html/rfc7468) sections for
+  // [General Considerations](https://tools.ietf.org/html/rfc7468#section-2) and
+  // [Textual Encoding of Subject Public Key Info]
+  // (https://tools.ietf.org/html/rfc7468#section-13).
+  string pem = 1;
+
+  // The [Algorithm][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionAlgorithm] associated
+  // with this key.
+  CryptoKeyVersion.CryptoKeyVersionAlgorithm algorithm = 2;
+}
+
+// [ProtectionLevel][google.cloud.kms.v1.ProtectionLevel] specifies how cryptographic operations are performed.
+enum ProtectionLevel {
+  // Not specified.
+  PROTECTION_LEVEL_UNSPECIFIED = 0;
+
+  // Crypto operations are performed in software.
+  SOFTWARE = 1;
+
+  // Crypto operations are performed in a Hardware Security Module.
+  HSM = 2;
+}
diff --git a/kms/google/cloud/kms_v1/proto/service.proto b/kms/google/cloud/kms_v1/proto/service.proto
new file mode 100644
index 000000000000..22026578c0f3
--- /dev/null
+++ b/kms/google/cloud/kms_v1/proto/service.proto
@@ -0,0 +1,554 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.kms.v1;
+
+import "google/api/annotations.proto";
+import "google/cloud/kms/v1/resources.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/wrappers.proto";
+
+option cc_enable_arenas = true;
+option csharp_namespace = "Google.Cloud.Kms.V1";
+option go_package = "google.golang.org/genproto/googleapis/cloud/kms/v1;kms";
+option java_multiple_files = true;
+option java_outer_classname = "KmsProto";
+option java_package = "com.google.cloud.kms.v1";
+option php_namespace = "Google\\Cloud\\Kms\\V1";
+
+
+// Google Cloud Key Management Service
+//
+// Manages cryptographic keys and operations using those keys. Implements a REST
+// model with the following objects:
+//
+// * [KeyRing][google.cloud.kms.v1.KeyRing]
+// * [CryptoKey][google.cloud.kms.v1.CryptoKey]
+// * [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]
+//
+// If you are using manual gRPC libraries, see
+// [Using gRPC with Cloud KMS](https://cloud.google.com/kms/docs/grpc).
+service KeyManagementService {
+  // Lists [KeyRings][google.cloud.kms.v1.KeyRing].
+  rpc ListKeyRings(ListKeyRingsRequest) returns (ListKeyRingsResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/locations/*}/keyRings"
+    };
+  }
+
+  // Lists [CryptoKeys][google.cloud.kms.v1.CryptoKey].
+  rpc ListCryptoKeys(ListCryptoKeysRequest) returns (ListCryptoKeysResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/locations/*/keyRings/*}/cryptoKeys"
+    };
+  }
+
+  // Lists [CryptoKeyVersions][google.cloud.kms.v1.CryptoKeyVersion].
+  rpc ListCryptoKeyVersions(ListCryptoKeyVersionsRequest) returns (ListCryptoKeyVersionsResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/locations/*/keyRings/*/cryptoKeys/*}/cryptoKeyVersions"
+    };
+  }
+
+  // Returns metadata for a given [KeyRing][google.cloud.kms.v1.KeyRing].
+  rpc GetKeyRing(GetKeyRingRequest) returns (KeyRing) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/keyRings/*}"
+    };
+  }
+
+  // Returns metadata for a given [CryptoKey][google.cloud.kms.v1.CryptoKey], as well as its
+  // [primary][google.cloud.kms.v1.CryptoKey.primary] [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion].
+  rpc GetCryptoKey(GetCryptoKeyRequest) returns (CryptoKey) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/*}"
+    };
+  }
+
+  // Returns metadata for a given [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion].
+  rpc GetCryptoKeyVersion(GetCryptoKeyVersionRequest) returns (CryptoKeyVersion) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/*/cryptoKeyVersions/*}"
+    };
+  }
+
+  // Returns the public key for the given [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]. The
+  // [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] must be
+  // [ASYMMETRIC_SIGN][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_SIGN] or
+  // [ASYMMETRIC_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_DECRYPT].
+  rpc GetPublicKey(GetPublicKeyRequest) returns (PublicKey) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/*/cryptoKeyVersions/*}/publicKey"
+    };
+  }
+
+  // Create a new [KeyRing][google.cloud.kms.v1.KeyRing] in a given Project and Location.
+  rpc CreateKeyRing(CreateKeyRingRequest) returns (KeyRing) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/locations/*}/keyRings"
+      body: "key_ring"
+    };
+  }
+
+  // Create a new [CryptoKey][google.cloud.kms.v1.CryptoKey] within a [KeyRing][google.cloud.kms.v1.KeyRing].
+  //
+  // [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] and
+  // [CryptoKey.version_template.algorithm][google.cloud.kms.v1.CryptoKeyVersionTemplate.algorithm]
+  // are required.
+  rpc CreateCryptoKey(CreateCryptoKeyRequest) returns (CryptoKey) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/locations/*/keyRings/*}/cryptoKeys"
+      body: "crypto_key"
+    };
+  }
+
+  // Create a new [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] in a [CryptoKey][google.cloud.kms.v1.CryptoKey].
+  //
+  // The server will assign the next sequential id. If unset,
+  // [state][google.cloud.kms.v1.CryptoKeyVersion.state] will be set to
+  // [ENABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.ENABLED].
+  rpc CreateCryptoKeyVersion(CreateCryptoKeyVersionRequest) returns (CryptoKeyVersion) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/locations/*/keyRings/*/cryptoKeys/*}/cryptoKeyVersions"
+      body: "crypto_key_version"
+    };
+  }
+
+  // Update a [CryptoKey][google.cloud.kms.v1.CryptoKey].
+  rpc UpdateCryptoKey(UpdateCryptoKeyRequest) returns (CryptoKey) {
+    option (google.api.http) = {
+      patch: "/v1/{crypto_key.name=projects/*/locations/*/keyRings/*/cryptoKeys/*}"
+      body: "crypto_key"
+    };
+  }
+
+  // Update a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]'s metadata.
+  //
+  // [state][google.cloud.kms.v1.CryptoKeyVersion.state] may be changed between
+  // [ENABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.ENABLED] and
+  // [DISABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DISABLED] using this
+  // method. See [DestroyCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.DestroyCryptoKeyVersion] and [RestoreCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.RestoreCryptoKeyVersion] to
+  // move between other states.
+  rpc UpdateCryptoKeyVersion(UpdateCryptoKeyVersionRequest) returns (CryptoKeyVersion) {
+    option (google.api.http) = {
+      patch: "/v1/{crypto_key_version.name=projects/*/locations/*/keyRings/*/cryptoKeys/*/cryptoKeyVersions/*}"
+      body: "crypto_key_version"
+    };
+  }
+
+  // Encrypts data, so that it can only be recovered by a call to [Decrypt][google.cloud.kms.v1.KeyManagementService.Decrypt].
+  // The [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] must be
+  // [ENCRYPT_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT].
+  rpc Encrypt(EncryptRequest) returns (EncryptResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/**}:encrypt"
+      body: "*"
+    };
+  }
+
+  // Decrypts data that was protected by [Encrypt][google.cloud.kms.v1.KeyManagementService.Encrypt]. The [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose]
+  // must be [ENCRYPT_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT].
+  rpc Decrypt(DecryptRequest) returns (DecryptResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/*}:decrypt"
+      body: "*"
+    };
+  }
+
+  // Signs data using a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] with [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose]
+  // ASYMMETRIC_SIGN, producing a signature that can be verified with the public
+  // key retrieved from [GetPublicKey][google.cloud.kms.v1.KeyManagementService.GetPublicKey].
+  rpc AsymmetricSign(AsymmetricSignRequest) returns (AsymmetricSignResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/*/cryptoKeyVersions/*}:asymmetricSign"
+      body: "*"
+    };
+  }
+
+  // Decrypts data that was encrypted with a public key retrieved from
+  // [GetPublicKey][google.cloud.kms.v1.KeyManagementService.GetPublicKey] corresponding to a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] with
+  // [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] ASYMMETRIC_DECRYPT.
+  rpc AsymmetricDecrypt(AsymmetricDecryptRequest) returns (AsymmetricDecryptResponse) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/*/cryptoKeyVersions/*}:asymmetricDecrypt"
+      body: "*"
+    };
+  }
+
+  // Update the version of a [CryptoKey][google.cloud.kms.v1.CryptoKey] that will be used in [Encrypt][google.cloud.kms.v1.KeyManagementService.Encrypt].
+  //
+  // Returns an error if called on an asymmetric key.
+  rpc UpdateCryptoKeyPrimaryVersion(UpdateCryptoKeyPrimaryVersionRequest) returns (CryptoKey) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/*}:updatePrimaryVersion"
+      body: "*"
+    };
+  }
+
+  // Schedule a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] for destruction.
+  //
+  // Upon calling this method, [CryptoKeyVersion.state][google.cloud.kms.v1.CryptoKeyVersion.state] will be set to
+  // [DESTROY_SCHEDULED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DESTROY_SCHEDULED]
+  // and [destroy_time][google.cloud.kms.v1.CryptoKeyVersion.destroy_time] will be set to a time 24
+  // hours in the future, at which point the [state][google.cloud.kms.v1.CryptoKeyVersion.state]
+  // will be changed to
+  // [DESTROYED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DESTROYED], and the key
+  // material will be irrevocably destroyed.
+  //
+  // Before the [destroy_time][google.cloud.kms.v1.CryptoKeyVersion.destroy_time] is reached,
+  // [RestoreCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.RestoreCryptoKeyVersion] may be called to reverse the process.
+  rpc DestroyCryptoKeyVersion(DestroyCryptoKeyVersionRequest) returns (CryptoKeyVersion) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/*/cryptoKeyVersions/*}:destroy"
+      body: "*"
+    };
+  }
+
+  // Restore a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] in the
+  // [DESTROY_SCHEDULED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DESTROY_SCHEDULED]
+  // state.
+  //
+  // Upon restoration of the CryptoKeyVersion, [state][google.cloud.kms.v1.CryptoKeyVersion.state]
+  // will be set to [DISABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DISABLED],
+  // and [destroy_time][google.cloud.kms.v1.CryptoKeyVersion.destroy_time] will be cleared.
+  rpc RestoreCryptoKeyVersion(RestoreCryptoKeyVersionRequest) returns (CryptoKeyVersion) {
+    option (google.api.http) = {
+      post: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/*/cryptoKeyVersions/*}:restore"
+      body: "*"
+    };
+  }
+}
+
+// Request message for [KeyManagementService.ListKeyRings][google.cloud.kms.v1.KeyManagementService.ListKeyRings].
+message ListKeyRingsRequest {
+  // Required. The resource name of the location associated with the
+  // [KeyRings][google.cloud.kms.v1.KeyRing], in the format `projects/*/locations/*`.
+  string parent = 1;
+
+  // Optional limit on the number of [KeyRings][google.cloud.kms.v1.KeyRing] to include in the
+  // response.  Further [KeyRings][google.cloud.kms.v1.KeyRing] can subsequently be obtained by
+  // including the [ListKeyRingsResponse.next_page_token][google.cloud.kms.v1.ListKeyRingsResponse.next_page_token] in a subsequent
+  // request.  If unspecified, the server will pick an appropriate default.
+  int32 page_size = 2;
+
+  // Optional pagination token, returned earlier via
+  // [ListKeyRingsResponse.next_page_token][google.cloud.kms.v1.ListKeyRingsResponse.next_page_token].
+  string page_token = 3;
+}
+
+// Request message for [KeyManagementService.ListCryptoKeys][google.cloud.kms.v1.KeyManagementService.ListCryptoKeys].
+message ListCryptoKeysRequest {
+  // Required. The resource name of the [KeyRing][google.cloud.kms.v1.KeyRing] to list, in the format
+  // `projects/*/locations/*/keyRings/*`.
+  string parent = 1;
+
+  // Optional limit on the number of [CryptoKeys][google.cloud.kms.v1.CryptoKey] to include in the
+  // response.  Further [CryptoKeys][google.cloud.kms.v1.CryptoKey] can subsequently be obtained by
+  // including the [ListCryptoKeysResponse.next_page_token][google.cloud.kms.v1.ListCryptoKeysResponse.next_page_token] in a subsequent
+  // request.  If unspecified, the server will pick an appropriate default.
+  int32 page_size = 2;
+
+  // Optional pagination token, returned earlier via
+  // [ListCryptoKeysResponse.next_page_token][google.cloud.kms.v1.ListCryptoKeysResponse.next_page_token].
+  string page_token = 3;
+
+  // The fields of the primary version to include in the response.
+  CryptoKeyVersion.CryptoKeyVersionView version_view = 4;
+}
+
+// Request message for [KeyManagementService.ListCryptoKeyVersions][google.cloud.kms.v1.KeyManagementService.ListCryptoKeyVersions].
+message ListCryptoKeyVersionsRequest {
+  // Required. The resource name of the [CryptoKey][google.cloud.kms.v1.CryptoKey] to list, in the format
+  // `projects/*/locations/*/keyRings/*/cryptoKeys/*`.
+  string parent = 1;
+
+  // Optional limit on the number of [CryptoKeyVersions][google.cloud.kms.v1.CryptoKeyVersion] to
+  // include in the response. Further [CryptoKeyVersions][google.cloud.kms.v1.CryptoKeyVersion] can
+  // subsequently be obtained by including the
+  // [ListCryptoKeyVersionsResponse.next_page_token][google.cloud.kms.v1.ListCryptoKeyVersionsResponse.next_page_token] in a subsequent request.
+  // If unspecified, the server will pick an appropriate default.
+  int32 page_size = 2;
+
+  // Optional pagination token, returned earlier via
+  // [ListCryptoKeyVersionsResponse.next_page_token][google.cloud.kms.v1.ListCryptoKeyVersionsResponse.next_page_token].
+  string page_token = 3;
+
+  // The fields to include in the response.
+  CryptoKeyVersion.CryptoKeyVersionView view = 4;
+}
+
+// Response message for [KeyManagementService.ListKeyRings][google.cloud.kms.v1.KeyManagementService.ListKeyRings].
+message ListKeyRingsResponse {
+  // The list of [KeyRings][google.cloud.kms.v1.KeyRing].
+  repeated KeyRing key_rings = 1;
+
+  // A token to retrieve next page of results. Pass this value in
+  // [ListKeyRingsRequest.page_token][google.cloud.kms.v1.ListKeyRingsRequest.page_token] to retrieve the next page of results.
+  string next_page_token = 2;
+
+  // The total number of [KeyRings][google.cloud.kms.v1.KeyRing] that matched the query.
+  int32 total_size = 3;
+}
+
+// Response message for [KeyManagementService.ListCryptoKeys][google.cloud.kms.v1.KeyManagementService.ListCryptoKeys].
+message ListCryptoKeysResponse {
+  // The list of [CryptoKeys][google.cloud.kms.v1.CryptoKey].
+  repeated CryptoKey crypto_keys = 1;
+
+  // A token to retrieve next page of results. Pass this value in
+  // [ListCryptoKeysRequest.page_token][google.cloud.kms.v1.ListCryptoKeysRequest.page_token] to retrieve the next page of results.
+  string next_page_token = 2;
+
+  // The total number of [CryptoKeys][google.cloud.kms.v1.CryptoKey] that matched the query.
+  int32 total_size = 3;
+}
+
+// Response message for [KeyManagementService.ListCryptoKeyVersions][google.cloud.kms.v1.KeyManagementService.ListCryptoKeyVersions].
+message ListCryptoKeyVersionsResponse {
+  // The list of [CryptoKeyVersions][google.cloud.kms.v1.CryptoKeyVersion].
+  repeated CryptoKeyVersion crypto_key_versions = 1;
+
+  // A token to retrieve next page of results. Pass this value in
+  // [ListCryptoKeyVersionsRequest.page_token][google.cloud.kms.v1.ListCryptoKeyVersionsRequest.page_token] to retrieve the next page of
+  // results.
+  string next_page_token = 2;
+
+  // The total number of [CryptoKeyVersions][google.cloud.kms.v1.CryptoKeyVersion] that matched the
+  // query.
+  int32 total_size = 3;
+}
+
+// Request message for [KeyManagementService.GetKeyRing][google.cloud.kms.v1.KeyManagementService.GetKeyRing].
+message GetKeyRingRequest {
+  // The [name][google.cloud.kms.v1.KeyRing.name] of the [KeyRing][google.cloud.kms.v1.KeyRing] to get.
+  string name = 1;
+}
+
+// Request message for [KeyManagementService.GetCryptoKey][google.cloud.kms.v1.KeyManagementService.GetCryptoKey].
+message GetCryptoKeyRequest {
+  // The [name][google.cloud.kms.v1.CryptoKey.name] of the [CryptoKey][google.cloud.kms.v1.CryptoKey] to get.
+  string name = 1;
+}
+
+// Request message for [KeyManagementService.GetCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.GetCryptoKeyVersion].
+message GetCryptoKeyVersionRequest {
+  // The [name][google.cloud.kms.v1.CryptoKeyVersion.name] of the [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] to get.
+  string name = 1;
+}
+
+// Request message for [KeyManagementService.GetPublicKey][google.cloud.kms.v1.KeyManagementService.GetPublicKey].
+message GetPublicKeyRequest {
+  // The [name][google.cloud.kms.v1.CryptoKeyVersion.name] of the [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] public key to
+  // get.
+  string name = 1;
+}
+
+// Request message for [KeyManagementService.CreateKeyRing][google.cloud.kms.v1.KeyManagementService.CreateKeyRing].
+message CreateKeyRingRequest {
+  // Required. The resource name of the location associated with the
+  // [KeyRings][google.cloud.kms.v1.KeyRing], in the format `projects/*/locations/*`.
+  string parent = 1;
+
+  // Required. It must be unique within a location and match the regular
+  // expression `[a-zA-Z0-9_-]{1,63}`
+  string key_ring_id = 2;
+
+  // A [KeyRing][google.cloud.kms.v1.KeyRing] with initial field values.
+  KeyRing key_ring = 3;
+}
+
+// Request message for [KeyManagementService.CreateCryptoKey][google.cloud.kms.v1.KeyManagementService.CreateCryptoKey].
+message CreateCryptoKeyRequest {
+  // Required. The [name][google.cloud.kms.v1.KeyRing.name] of the KeyRing associated with the
+  // [CryptoKeys][google.cloud.kms.v1.CryptoKey].
+  string parent = 1;
+
+  // Required. It must be unique within a KeyRing and match the regular
+  // expression `[a-zA-Z0-9_-]{1,63}`
+  string crypto_key_id = 2;
+
+  // A [CryptoKey][google.cloud.kms.v1.CryptoKey] with initial field values.
+  CryptoKey crypto_key = 3;
+}
+
+// Request message for [KeyManagementService.CreateCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.CreateCryptoKeyVersion].
+message CreateCryptoKeyVersionRequest {
+  // Required. The [name][google.cloud.kms.v1.CryptoKey.name] of the [CryptoKey][google.cloud.kms.v1.CryptoKey] associated with
+  // the [CryptoKeyVersions][google.cloud.kms.v1.CryptoKeyVersion].
+  string parent = 1;
+
+  // A [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] with initial field values.
+  CryptoKeyVersion crypto_key_version = 2;
+}
+
+// Request message for [KeyManagementService.UpdateCryptoKey][google.cloud.kms.v1.KeyManagementService.UpdateCryptoKey].
+message UpdateCryptoKeyRequest {
+  // [CryptoKey][google.cloud.kms.v1.CryptoKey] with updated values.
+  CryptoKey crypto_key = 1;
+
+  // Required list of fields to be updated in this request.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for [KeyManagementService.UpdateCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.UpdateCryptoKeyVersion].
+message UpdateCryptoKeyVersionRequest {
+  // [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] with updated values.
+  CryptoKeyVersion crypto_key_version = 1;
+
+  // Required list of fields to be updated in this request.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for [KeyManagementService.Encrypt][google.cloud.kms.v1.KeyManagementService.Encrypt].
+message EncryptRequest {
+  // Required. The resource name of the [CryptoKey][google.cloud.kms.v1.CryptoKey] or [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]
+  // to use for encryption.
+  //
+  // If a [CryptoKey][google.cloud.kms.v1.CryptoKey] is specified, the server will use its
+  // [primary version][google.cloud.kms.v1.CryptoKey.primary].
+  string name = 1;
+
+  // Required. The data to encrypt. Must be no larger than 64KiB.
+  //
+  // The maximum size depends on the key version's
+  // [protection_level][google.cloud.kms.v1.CryptoKeyVersionTemplate.protection_level]. For
+  // [SOFTWARE][google.cloud.kms.v1.ProtectionLevel.SOFTWARE] keys, the plaintext must be no larger
+  // than 64KiB. For [HSM][google.cloud.kms.v1.ProtectionLevel.HSM] keys, the combined length of the
+  // plaintext and additional_authenticated_data fields must be no larger than
+  // 8KiB.
+  bytes plaintext = 2;
+
+  // Optional data that, if specified, must also be provided during decryption
+  // through [DecryptRequest.additional_authenticated_data][google.cloud.kms.v1.DecryptRequest.additional_authenticated_data].
+  //
+  // The maximum size depends on the key version's
+  // [protection_level][google.cloud.kms.v1.CryptoKeyVersionTemplate.protection_level]. For
+  // [SOFTWARE][google.cloud.kms.v1.ProtectionLevel.SOFTWARE] keys, the AAD must be no larger than
+  // 64KiB. For [HSM][google.cloud.kms.v1.ProtectionLevel.HSM] keys, the combined length of the
+  // plaintext and additional_authenticated_data fields must be no larger than
+  // 8KiB.
+  bytes additional_authenticated_data = 3;
+}
+
+// Request message for [KeyManagementService.Decrypt][google.cloud.kms.v1.KeyManagementService.Decrypt].
+message DecryptRequest {
+  // Required. The resource name of the [CryptoKey][google.cloud.kms.v1.CryptoKey] to use for decryption.
+  // The server will choose the appropriate version.
+  string name = 1;
+
+  // Required. The encrypted data originally returned in
+  // [EncryptResponse.ciphertext][google.cloud.kms.v1.EncryptResponse.ciphertext].
+  bytes ciphertext = 2;
+
+  // Optional data that must match the data originally supplied in
+  // [EncryptRequest.additional_authenticated_data][google.cloud.kms.v1.EncryptRequest.additional_authenticated_data].
+  bytes additional_authenticated_data = 3;
+}
+
+// Request message for [KeyManagementService.AsymmetricSign][google.cloud.kms.v1.KeyManagementService.AsymmetricSign].
+message AsymmetricSignRequest {
+  // Required. The resource name of the [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] to use for signing.
+  string name = 1;
+
+  // Required. The digest of the data to sign. The digest must be produced with
+  // the same digest algorithm as specified by the key version's
+  // [algorithm][google.cloud.kms.v1.CryptoKeyVersion.algorithm].
+  Digest digest = 3;
+}
+
+// Request message for [KeyManagementService.AsymmetricDecrypt][google.cloud.kms.v1.KeyManagementService.AsymmetricDecrypt].
+message AsymmetricDecryptRequest {
+  // Required. The resource name of the [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] to use for
+  // decryption.
+  string name = 1;
+
+  // Required. The data encrypted with the named [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]'s public
+  // key using OAEP.
+  bytes ciphertext = 3;
+}
+
+// Response message for [KeyManagementService.Decrypt][google.cloud.kms.v1.KeyManagementService.Decrypt].
+message DecryptResponse {
+  // The decrypted data originally supplied in [EncryptRequest.plaintext][google.cloud.kms.v1.EncryptRequest.plaintext].
+  bytes plaintext = 1;
+}
+
+// Response message for [KeyManagementService.Encrypt][google.cloud.kms.v1.KeyManagementService.Encrypt].
+message EncryptResponse {
+  // The resource name of the [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] used in encryption.
+  string name = 1;
+
+  // The encrypted data.
+  bytes ciphertext = 2;
+}
+
+// Response message for [KeyManagementService.AsymmetricSign][google.cloud.kms.v1.KeyManagementService.AsymmetricSign].
+message AsymmetricSignResponse {
+  // The created signature.
+  bytes signature = 1;
+}
+
+// Response message for [KeyManagementService.AsymmetricDecrypt][google.cloud.kms.v1.KeyManagementService.AsymmetricDecrypt].
+message AsymmetricDecryptResponse {
+  // The decrypted data originally encrypted with the matching public key.
+  bytes plaintext = 1;
+}
+
+// Request message for [KeyManagementService.UpdateCryptoKeyPrimaryVersion][google.cloud.kms.v1.KeyManagementService.UpdateCryptoKeyPrimaryVersion].
+message UpdateCryptoKeyPrimaryVersionRequest {
+  // The resource name of the [CryptoKey][google.cloud.kms.v1.CryptoKey] to update.
+  string name = 1;
+
+  // The id of the child [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] to use as primary.
+  string crypto_key_version_id = 2;
+}
+
+// Request message for [KeyManagementService.DestroyCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.DestroyCryptoKeyVersion].
+message DestroyCryptoKeyVersionRequest {
+  // The resource name of the [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] to destroy.
+  string name = 1;
+}
+
+// Request message for [KeyManagementService.RestoreCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.RestoreCryptoKeyVersion].
+message RestoreCryptoKeyVersionRequest {
+  // The resource name of the [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] to restore.
+  string name = 1;
+}
+
+// A [Digest][google.cloud.kms.v1.Digest] holds a cryptographic message digest.
+message Digest {
+  // Required. The message digest.
+  oneof digest {
+    // A message digest produced with the SHA-256 algorithm.
+    bytes sha256 = 1;
+
+    // A message digest produced with the SHA-384 algorithm.
+    bytes sha384 = 2;
+
+    // A message digest produced with the SHA-512 algorithm.
+    bytes sha512 = 3;
+  }
+}
+
+// Cloud KMS metadata for the given [google.cloud.location.Location][google.cloud.location.Location].
+message LocationMetadata {
+  // Indicates whether [CryptoKeys][google.cloud.kms.v1.CryptoKey] with
+  // [protection_level][google.cloud.kms.v1.CryptoKeyVersionTemplate.protection_level]
+  // [HSM][google.cloud.kms.v1.ProtectionLevel.HSM] can be created in this location.
+  bool hsm_available = 1;
+}
diff --git a/kms/synth.metadata b/kms/synth.metadata
index e9ac7c9ed164..dc515424d997 100644
--- a/kms/synth.metadata
+++ b/kms/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:20:48.753313Z",
+  "updateTime": "2019-01-24T05:39:02.695222Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
@@ -29,7 +29,7 @@
       "client": {
         "source": "googleapis",
         "apiName": "kms",
-        "apiVersion": "v1beta1",
+        "apiVersion": "v1",
         "language": "python",
         "generator": "gapic",
         "config": "google/cloud/kms/artman_cloudkms.yaml"
diff --git a/kms/synth.py b/kms/synth.py
index 00e8a24a6a3c..c216ae7b85f1 100644
--- a/kms/synth.py
+++ b/kms/synth.py
@@ -24,13 +24,17 @@
 
 gapic = gcp.GAPICGenerator()
 common = gcp.CommonTemplates()
-version = "v1beta1"
+version = "v1"
 
 # ----------------------------------------------------------------------------
 # Generate kms GAPIC layer
 # ----------------------------------------------------------------------------
 library = gapic.py_library(
-    "kms", version, config_path="artman_cloudkms.yaml", artman_output_name="kms-v1"
+    "kms",
+    version,
+    config_path="artman_cloudkms.yaml",
+    artman_output_name="kms-v1",
+    include_protos=True,
 )
 
 s.move(library, excludes=["README.rst", "setup.py", "nox*.py", "docs/**/*"])
diff --git a/language/google/cloud/language_v1/proto/language_service.proto b/language/google/cloud/language_v1/proto/language_service.proto
new file mode 100644
index 000000000000..27212ac726c4
--- /dev/null
+++ b/language/google/cloud/language_v1/proto/language_service.proto
@@ -0,0 +1,950 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.language.v1beta1;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/language/v1beta1;language";
+option java_multiple_files = true;
+option java_outer_classname = "LanguageServiceProto";
+option java_package = "com.google.cloud.language.v1beta1";
+
+
+// Provides text analysis operations such as sentiment analysis and entity
+// recognition.
+service LanguageService {
+  // Analyzes the sentiment of the provided text.
+  rpc AnalyzeSentiment(AnalyzeSentimentRequest) returns (AnalyzeSentimentResponse) {
+    option (google.api.http) = { post: "/v1beta1/documents:analyzeSentiment" body: "*" };
+  }
+
+  // Finds named entities (currently proper names and common nouns) in the text
+  // along with entity types, salience, mentions for each entity, and
+  // other properties.
+  rpc AnalyzeEntities(AnalyzeEntitiesRequest) returns (AnalyzeEntitiesResponse) {
+    option (google.api.http) = { post: "/v1beta1/documents:analyzeEntities" body: "*" };
+  }
+
+  // Analyzes the syntax of the text and provides sentence boundaries and
+  // tokenization along with part of speech tags, dependency trees, and other
+  // properties.
+  rpc AnalyzeSyntax(AnalyzeSyntaxRequest) returns (AnalyzeSyntaxResponse) {
+    option (google.api.http) = { post: "/v1beta1/documents:analyzeSyntax" body: "*" };
+  }
+
+  // A convenience method that provides all the features that analyzeSentiment,
+  // analyzeEntities, and analyzeSyntax provide in one call.
+  rpc AnnotateText(AnnotateTextRequest) returns (AnnotateTextResponse) {
+    option (google.api.http) = { post: "/v1beta1/documents:annotateText" body: "*" };
+  }
+}
+
+// ################################################################ #
+//
+// Represents the input to API methods.
+message Document {
+  // The document types enum.
+  enum Type {
+    // The content type is not specified.
+    TYPE_UNSPECIFIED = 0;
+
+    // Plain text
+    PLAIN_TEXT = 1;
+
+    // HTML
+    HTML = 2;
+  }
+
+  // Required. If the type is not set or is `TYPE_UNSPECIFIED`,
+  // returns an `INVALID_ARGUMENT` error.
+  Type type = 1;
+
+  // The source of the document: a string containing the content or a
+  // Google Cloud Storage URI.
+  oneof source {
+    // The content of the input in string format.
+    string content = 2;
+
+    // The Google Cloud Storage URI where the file content is located.
+    // This URI must be of the form: gs://bucket_name/object_name. For more
+    // details, see https://cloud.google.com/storage/docs/reference-uris.
+    // NOTE: Cloud Storage object versioning is not supported.
+    string gcs_content_uri = 3;
+  }
+
+  // The language of the document (if not specified, the language is
+  // automatically detected). Both ISO and BCP-47 language codes are
+  // accepted.<br>
+  // [Language Support](https://cloud.google.com/natural-language/docs/languages)
+  // lists currently supported languages for each API method.
+  // If the language (either specified by the caller or automatically detected)
+  // is not supported by the called API method, an `INVALID_ARGUMENT` error
+  // is returned.
+  string language = 4;
+}
+
+// Represents a sentence in the input document.
+message Sentence {
+  // The sentence text.
+  TextSpan text = 1;
+
+  // For calls to [AnalyzeSentiment][] or if
+  // [AnnotateTextRequest.Features.extract_document_sentiment][google.cloud.language.v1beta1.AnnotateTextRequest.Features.extract_document_sentiment] is set to
+  // true, this field will contain the sentiment for the sentence.
+  Sentiment sentiment = 2;
+}
+
+// Represents a phrase in the text that is a known entity, such as
+// a person, an organization, or location. The API associates information, such
+// as salience and mentions, with entities.
+message Entity {
+  // The type of the entity.
+  enum Type {
+    // Unknown
+    UNKNOWN = 0;
+
+    // Person
+    PERSON = 1;
+
+    // Location
+    LOCATION = 2;
+
+    // Organization
+    ORGANIZATION = 3;
+
+    // Event
+    EVENT = 4;
+
+    // Work of art
+    WORK_OF_ART = 5;
+
+    // Consumer goods
+    CONSUMER_GOOD = 6;
+
+    // Other types
+    OTHER = 7;
+  }
+
+  // The representative name for the entity.
+  string name = 1;
+
+  // The entity type.
+  Type type = 2;
+
+  // Metadata associated with the entity.
+  //
+  // Currently, Wikipedia URLs and Knowledge Graph MIDs are provided, if
+  // available. The associated keys are "wikipedia_url" and "mid", respectively.
+  map<string, string> metadata = 3;
+
+  // The salience score associated with the entity in the [0, 1.0] range.
+  //
+  // The salience score for an entity provides information about the
+  // importance or centrality of that entity to the entire document text.
+  // Scores closer to 0 are less salient, while scores closer to 1.0 are highly
+  // salient.
+  float salience = 4;
+
+  // The mentions of this entity in the input document. The API currently
+  // supports proper noun mentions.
+  repeated EntityMention mentions = 5;
+}
+
+// Represents the smallest syntactic building block of the text.
+message Token {
+  // The token text.
+  TextSpan text = 1;
+
+  // Parts of speech tag for this token.
+  PartOfSpeech part_of_speech = 2;
+
+  // Dependency tree parse for this token.
+  DependencyEdge dependency_edge = 3;
+
+  // [Lemma](https://en.wikipedia.org/wiki/Lemma_%28morphology%29) of the token.
+  string lemma = 4;
+}
+
+// Represents the feeling associated with the entire text or entities in
+// the text.
+message Sentiment {
+  // DEPRECATED FIELD - This field is being deprecated in
+  // favor of score. Please refer to our documentation at
+  // https://cloud.google.com/natural-language/docs for more information.
+  float polarity = 1;
+
+  // A non-negative number in the [0, +inf) range, which represents
+  // the absolute magnitude of sentiment regardless of score (positive or
+  // negative).
+  float magnitude = 2;
+
+  // Sentiment score between -1.0 (negative sentiment) and 1.0
+  // (positive sentiment).
+  float score = 3;
+}
+
+// Represents part of speech information for a token.
+message PartOfSpeech {
+  // The part of speech tags enum.
+  enum Tag {
+    // Unknown
+    UNKNOWN = 0;
+
+    // Adjective
+    ADJ = 1;
+
+    // Adposition (preposition and postposition)
+    ADP = 2;
+
+    // Adverb
+    ADV = 3;
+
+    // Conjunction
+    CONJ = 4;
+
+    // Determiner
+    DET = 5;
+
+    // Noun (common and proper)
+    NOUN = 6;
+
+    // Cardinal number
+    NUM = 7;
+
+    // Pronoun
+    PRON = 8;
+
+    // Particle or other function word
+    PRT = 9;
+
+    // Punctuation
+    PUNCT = 10;
+
+    // Verb (all tenses and modes)
+    VERB = 11;
+
+    // Other: foreign words, typos, abbreviations
+    X = 12;
+
+    // Affix
+    AFFIX = 13;
+  }
+
+  // The characteristic of a verb that expresses time flow during an event.
+  enum Aspect {
+    // Aspect is not applicable in the analyzed language or is not predicted.
+    ASPECT_UNKNOWN = 0;
+
+    // Perfective
+    PERFECTIVE = 1;
+
+    // Imperfective
+    IMPERFECTIVE = 2;
+
+    // Progressive
+    PROGRESSIVE = 3;
+  }
+
+  // The grammatical function performed by a noun or pronoun in a phrase,
+  // clause, or sentence. In some languages, other parts of speech, such as
+  // adjective and determiner, take case inflection in agreement with the noun.
+  enum Case {
+    // Case is not applicable in the analyzed language or is not predicted.
+    CASE_UNKNOWN = 0;
+
+    // Accusative
+    ACCUSATIVE = 1;
+
+    // Adverbial
+    ADVERBIAL = 2;
+
+    // Complementive
+    COMPLEMENTIVE = 3;
+
+    // Dative
+    DATIVE = 4;
+
+    // Genitive
+    GENITIVE = 5;
+
+    // Instrumental
+    INSTRUMENTAL = 6;
+
+    // Locative
+    LOCATIVE = 7;
+
+    // Nominative
+    NOMINATIVE = 8;
+
+    // Oblique
+    OBLIQUE = 9;
+
+    // Partitive
+    PARTITIVE = 10;
+
+    // Prepositional
+    PREPOSITIONAL = 11;
+
+    // Reflexive
+    REFLEXIVE_CASE = 12;
+
+    // Relative
+    RELATIVE_CASE = 13;
+
+    // Vocative
+    VOCATIVE = 14;
+  }
+
+  // Depending on the language, Form can be categorizing different forms of
+  // verbs, adjectives, adverbs, etc. For example, categorizing inflected
+  // endings of verbs and adjectives or distinguishing between short and long
+  // forms of adjectives and participles
+  enum Form {
+    // Form is not applicable in the analyzed language or is not predicted.
+    FORM_UNKNOWN = 0;
+
+    // Adnomial
+    ADNOMIAL = 1;
+
+    // Auxiliary
+    AUXILIARY = 2;
+
+    // Complementizer
+    COMPLEMENTIZER = 3;
+
+    // Final ending
+    FINAL_ENDING = 4;
+
+    // Gerund
+    GERUND = 5;
+
+    // Realis
+    REALIS = 6;
+
+    // Irrealis
+    IRREALIS = 7;
+
+    // Short form
+    SHORT = 8;
+
+    // Long form
+    LONG = 9;
+
+    // Order form
+    ORDER = 10;
+
+    // Specific form
+    SPECIFIC = 11;
+  }
+
+  // Gender classes of nouns reflected in the behaviour of associated words.
+  enum Gender {
+    // Gender is not applicable in the analyzed language or is not predicted.
+    GENDER_UNKNOWN = 0;
+
+    // Feminine
+    FEMININE = 1;
+
+    // Masculine
+    MASCULINE = 2;
+
+    // Neuter
+    NEUTER = 3;
+  }
+
+  // The grammatical feature of verbs, used for showing modality and attitude.
+  enum Mood {
+    // Mood is not applicable in the analyzed language or is not predicted.
+    MOOD_UNKNOWN = 0;
+
+    // Conditional
+    CONDITIONAL_MOOD = 1;
+
+    // Imperative
+    IMPERATIVE = 2;
+
+    // Indicative
+    INDICATIVE = 3;
+
+    // Interrogative
+    INTERROGATIVE = 4;
+
+    // Jussive
+    JUSSIVE = 5;
+
+    // Subjunctive
+    SUBJUNCTIVE = 6;
+  }
+
+  // Count distinctions.
+  enum Number {
+    // Number is not applicable in the analyzed language or is not predicted.
+    NUMBER_UNKNOWN = 0;
+
+    // Singular
+    SINGULAR = 1;
+
+    // Plural
+    PLURAL = 2;
+
+    // Dual
+    DUAL = 3;
+  }
+
+  // The distinction between the speaker, second person, third person, etc.
+  enum Person {
+    // Person is not applicable in the analyzed language or is not predicted.
+    PERSON_UNKNOWN = 0;
+
+    // First
+    FIRST = 1;
+
+    // Second
+    SECOND = 2;
+
+    // Third
+    THIRD = 3;
+
+    // Reflexive
+    REFLEXIVE_PERSON = 4;
+  }
+
+  // This category shows if the token is part of a proper name.
+  enum Proper {
+    // Proper is not applicable in the analyzed language or is not predicted.
+    PROPER_UNKNOWN = 0;
+
+    // Proper
+    PROPER = 1;
+
+    // Not proper
+    NOT_PROPER = 2;
+  }
+
+  // Reciprocal features of a pronoun.
+  enum Reciprocity {
+    // Reciprocity is not applicable in the analyzed language or is not
+    // predicted.
+    RECIPROCITY_UNKNOWN = 0;
+
+    // Reciprocal
+    RECIPROCAL = 1;
+
+    // Non-reciprocal
+    NON_RECIPROCAL = 2;
+  }
+
+  // Time reference.
+  enum Tense {
+    // Tense is not applicable in the analyzed language or is not predicted.
+    TENSE_UNKNOWN = 0;
+
+    // Conditional
+    CONDITIONAL_TENSE = 1;
+
+    // Future
+    FUTURE = 2;
+
+    // Past
+    PAST = 3;
+
+    // Present
+    PRESENT = 4;
+
+    // Imperfect
+    IMPERFECT = 5;
+
+    // Pluperfect
+    PLUPERFECT = 6;
+  }
+
+  // The relationship between the action that a verb expresses and the
+  // participants identified by its arguments.
+  enum Voice {
+    // Voice is not applicable in the analyzed language or is not predicted.
+    VOICE_UNKNOWN = 0;
+
+    // Active
+    ACTIVE = 1;
+
+    // Causative
+    CAUSATIVE = 2;
+
+    // Passive
+    PASSIVE = 3;
+  }
+
+  // The part of speech tag.
+  Tag tag = 1;
+
+  // The grammatical aspect.
+  Aspect aspect = 2;
+
+  // The grammatical case.
+  Case case = 3;
+
+  // The grammatical form.
+  Form form = 4;
+
+  // The grammatical gender.
+  Gender gender = 5;
+
+  // The grammatical mood.
+  Mood mood = 6;
+
+  // The grammatical number.
+  Number number = 7;
+
+  // The grammatical person.
+  Person person = 8;
+
+  // The grammatical properness.
+  Proper proper = 9;
+
+  // The grammatical reciprocity.
+  Reciprocity reciprocity = 10;
+
+  // The grammatical tense.
+  Tense tense = 11;
+
+  // The grammatical voice.
+  Voice voice = 12;
+}
+
+// Represents dependency parse tree information for a token.
+message DependencyEdge {
+  // The parse label enum for the token.
+  enum Label {
+    // Unknown
+    UNKNOWN = 0;
+
+    // Abbreviation modifier
+    ABBREV = 1;
+
+    // Adjectival complement
+    ACOMP = 2;
+
+    // Adverbial clause modifier
+    ADVCL = 3;
+
+    // Adverbial modifier
+    ADVMOD = 4;
+
+    // Adjectival modifier of an NP
+    AMOD = 5;
+
+    // Appositional modifier of an NP
+    APPOS = 6;
+
+    // Attribute dependent of a copular verb
+    ATTR = 7;
+
+    // Auxiliary (non-main) verb
+    AUX = 8;
+
+    // Passive auxiliary
+    AUXPASS = 9;
+
+    // Coordinating conjunction
+    CC = 10;
+
+    // Clausal complement of a verb or adjective
+    CCOMP = 11;
+
+    // Conjunct
+    CONJ = 12;
+
+    // Clausal subject
+    CSUBJ = 13;
+
+    // Clausal passive subject
+    CSUBJPASS = 14;
+
+    // Dependency (unable to determine)
+    DEP = 15;
+
+    // Determiner
+    DET = 16;
+
+    // Discourse
+    DISCOURSE = 17;
+
+    // Direct object
+    DOBJ = 18;
+
+    // Expletive
+    EXPL = 19;
+
+    // Goes with (part of a word in a text not well edited)
+    GOESWITH = 20;
+
+    // Indirect object
+    IOBJ = 21;
+
+    // Marker (word introducing a subordinate clause)
+    MARK = 22;
+
+    // Multi-word expression
+    MWE = 23;
+
+    // Multi-word verbal expression
+    MWV = 24;
+
+    // Negation modifier
+    NEG = 25;
+
+    // Noun compound modifier
+    NN = 26;
+
+    // Noun phrase used as an adverbial modifier
+    NPADVMOD = 27;
+
+    // Nominal subject
+    NSUBJ = 28;
+
+    // Passive nominal subject
+    NSUBJPASS = 29;
+
+    // Numeric modifier of a noun
+    NUM = 30;
+
+    // Element of compound number
+    NUMBER = 31;
+
+    // Punctuation mark
+    P = 32;
+
+    // Parataxis relation
+    PARATAXIS = 33;
+
+    // Participial modifier
+    PARTMOD = 34;
+
+    // The complement of a preposition is a clause
+    PCOMP = 35;
+
+    // Object of a preposition
+    POBJ = 36;
+
+    // Possession modifier
+    POSS = 37;
+
+    // Postverbal negative particle
+    POSTNEG = 38;
+
+    // Predicate complement
+    PRECOMP = 39;
+
+    // Preconjunt
+    PRECONJ = 40;
+
+    // Predeterminer
+    PREDET = 41;
+
+    // Prefix
+    PREF = 42;
+
+    // Prepositional modifier
+    PREP = 43;
+
+    // The relationship between a verb and verbal morpheme
+    PRONL = 44;
+
+    // Particle
+    PRT = 45;
+
+    // Associative or possessive marker
+    PS = 46;
+
+    // Quantifier phrase modifier
+    QUANTMOD = 47;
+
+    // Relative clause modifier
+    RCMOD = 48;
+
+    // Complementizer in relative clause
+    RCMODREL = 49;
+
+    // Ellipsis without a preceding predicate
+    RDROP = 50;
+
+    // Referent
+    REF = 51;
+
+    // Remnant
+    REMNANT = 52;
+
+    // Reparandum
+    REPARANDUM = 53;
+
+    // Root
+    ROOT = 54;
+
+    // Suffix specifying a unit of number
+    SNUM = 55;
+
+    // Suffix
+    SUFF = 56;
+
+    // Temporal modifier
+    TMOD = 57;
+
+    // Topic marker
+    TOPIC = 58;
+
+    // Clause headed by an infinite form of the verb that modifies a noun
+    VMOD = 59;
+
+    // Vocative
+    VOCATIVE = 60;
+
+    // Open clausal complement
+    XCOMP = 61;
+
+    // Name suffix
+    SUFFIX = 62;
+
+    // Name title
+    TITLE = 63;
+
+    // Adverbial phrase modifier
+    ADVPHMOD = 64;
+
+    // Causative auxiliary
+    AUXCAUS = 65;
+
+    // Helper auxiliary
+    AUXVV = 66;
+
+    // Rentaishi (Prenominal modifier)
+    DTMOD = 67;
+
+    // Foreign words
+    FOREIGN = 68;
+
+    // Keyword
+    KW = 69;
+
+    // List for chains of comparable items
+    LIST = 70;
+
+    // Nominalized clause
+    NOMC = 71;
+
+    // Nominalized clausal subject
+    NOMCSUBJ = 72;
+
+    // Nominalized clausal passive
+    NOMCSUBJPASS = 73;
+
+    // Compound of numeric modifier
+    NUMC = 74;
+
+    // Copula
+    COP = 75;
+
+    // Dislocated relation (for fronted/topicalized elements)
+    DISLOCATED = 76;
+  }
+
+  // Represents the head of this token in the dependency tree.
+  // This is the index of the token which has an arc going to this token.
+  // The index is the position of the token in the array of tokens returned
+  // by the API method. If this token is a root token, then the
+  // `head_token_index` is its own index.
+  int32 head_token_index = 1;
+
+  // The parse label for the token.
+  Label label = 2;
+}
+
+// Represents a mention for an entity in the text. Currently, proper noun
+// mentions are supported.
+message EntityMention {
+  // The supported types of mentions.
+  enum Type {
+    // Unknown
+    TYPE_UNKNOWN = 0;
+
+    // Proper name
+    PROPER = 1;
+
+    // Common noun (or noun compound)
+    COMMON = 2;
+  }
+
+  // The mention text.
+  TextSpan text = 1;
+
+  // The type of the entity mention.
+  Type type = 2;
+}
+
+// Represents an output piece of text.
+message TextSpan {
+  // The content of the output text.
+  string content = 1;
+
+  // The API calculates the beginning offset of the content in the original
+  // document according to the [EncodingType][google.cloud.language.v1beta1.EncodingType] specified in the API request.
+  int32 begin_offset = 2;
+}
+
+// The sentiment analysis request message.
+message AnalyzeSentimentRequest {
+  // Input document.
+  Document document = 1;
+
+  // The encoding type used by the API to calculate sentence offsets for the
+  // sentence sentiment.
+  EncodingType encoding_type = 2;
+}
+
+// The sentiment analysis response message.
+message AnalyzeSentimentResponse {
+  // The overall sentiment of the input document.
+  Sentiment document_sentiment = 1;
+
+  // The language of the text, which will be the same as the language specified
+  // in the request or, if not specified, the automatically-detected language.
+  // See [Document.language][google.cloud.language.v1beta1.Document.language] field for more details.
+  string language = 2;
+
+  // The sentiment for all the sentences in the document.
+  repeated Sentence sentences = 3;
+}
+
+// The entity analysis request message.
+message AnalyzeEntitiesRequest {
+  // Input document.
+  Document document = 1;
+
+  // The encoding type used by the API to calculate offsets.
+  EncodingType encoding_type = 2;
+}
+
+// The entity analysis response message.
+message AnalyzeEntitiesResponse {
+  // The recognized entities in the input document.
+  repeated Entity entities = 1;
+
+  // The language of the text, which will be the same as the language specified
+  // in the request or, if not specified, the automatically-detected language.
+  // See [Document.language][google.cloud.language.v1beta1.Document.language] field for more details.
+  string language = 2;
+}
+
+// The syntax analysis request message.
+message AnalyzeSyntaxRequest {
+  // Input document.
+  Document document = 1;
+
+  // The encoding type used by the API to calculate offsets.
+  EncodingType encoding_type = 2;
+}
+
+// The syntax analysis response message.
+message AnalyzeSyntaxResponse {
+  // Sentences in the input document.
+  repeated Sentence sentences = 1;
+
+  // Tokens, along with their syntactic information, in the input document.
+  repeated Token tokens = 2;
+
+  // The language of the text, which will be the same as the language specified
+  // in the request or, if not specified, the automatically-detected language.
+  // See [Document.language][google.cloud.language.v1beta1.Document.language] field for more details.
+  string language = 3;
+}
+
+// The request message for the text annotation API, which can perform multiple
+// analysis types (sentiment, entities, and syntax) in one call.
+message AnnotateTextRequest {
+  // All available features for sentiment, syntax, and semantic analysis.
+  // Setting each one to true will enable that specific analysis for the input.
+  message Features {
+    // Extract syntax information.
+    bool extract_syntax = 1;
+
+    // Extract entities.
+    bool extract_entities = 2;
+
+    // Extract document-level sentiment.
+    bool extract_document_sentiment = 3;
+  }
+
+  // Input document.
+  Document document = 1;
+
+  // The enabled features.
+  Features features = 2;
+
+  // The encoding type used by the API to calculate offsets.
+  EncodingType encoding_type = 3;
+}
+
+// The text annotations response message.
+message AnnotateTextResponse {
+  // Sentences in the input document. Populated if the user enables
+  // [AnnotateTextRequest.Features.extract_syntax][google.cloud.language.v1beta1.AnnotateTextRequest.Features.extract_syntax].
+  repeated Sentence sentences = 1;
+
+  // Tokens, along with their syntactic information, in the input document.
+  // Populated if the user enables
+  // [AnnotateTextRequest.Features.extract_syntax][google.cloud.language.v1beta1.AnnotateTextRequest.Features.extract_syntax].
+  repeated Token tokens = 2;
+
+  // Entities, along with their semantic information, in the input document.
+  // Populated if the user enables
+  // [AnnotateTextRequest.Features.extract_entities][google.cloud.language.v1beta1.AnnotateTextRequest.Features.extract_entities].
+  repeated Entity entities = 3;
+
+  // The overall sentiment for the document. Populated if the user enables
+  // [AnnotateTextRequest.Features.extract_document_sentiment][google.cloud.language.v1beta1.AnnotateTextRequest.Features.extract_document_sentiment].
+  Sentiment document_sentiment = 4;
+
+  // The language of the text, which will be the same as the language specified
+  // in the request or, if not specified, the automatically-detected language.
+  // See [Document.language][google.cloud.language.v1beta1.Document.language] field for more details.
+  string language = 5;
+}
+
+// Represents the text encoding that the caller uses to process the output.
+// Providing an `EncodingType` is recommended because the API provides the
+// beginning offsets for various outputs, such as tokens and mentions, and
+// languages that natively use different text encodings may access offsets
+// differently.
+enum EncodingType {
+  // If `EncodingType` is not specified, encoding-dependent information (such as
+  // `begin_offset`) will be set at `-1`.
+  NONE = 0;
+
+  // Encoding-dependent information (such as `begin_offset`) is calculated based
+  // on the UTF-8 encoding of the input. C++ and Go are examples of languages
+  // that use this encoding natively.
+  UTF8 = 1;
+
+  // Encoding-dependent information (such as `begin_offset`) is calculated based
+  // on the UTF-16 encoding of the input. Java and Javascript are examples of
+  // languages that use this encoding natively.
+  UTF16 = 2;
+
+  // Encoding-dependent information (such as `begin_offset`) is calculated based
+  // on the UTF-32 encoding of the input. Python is an example of a language
+  // that uses this encoding natively.
+  UTF32 = 3;
+}
diff --git a/language/google/cloud/language_v1beta2/proto/language_service.proto b/language/google/cloud/language_v1beta2/proto/language_service.proto
new file mode 100644
index 000000000000..27212ac726c4
--- /dev/null
+++ b/language/google/cloud/language_v1beta2/proto/language_service.proto
@@ -0,0 +1,950 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.language.v1beta1;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/language/v1beta1;language";
+option java_multiple_files = true;
+option java_outer_classname = "LanguageServiceProto";
+option java_package = "com.google.cloud.language.v1beta1";
+
+
+// Provides text analysis operations such as sentiment analysis and entity
+// recognition.
+service LanguageService {
+  // Analyzes the sentiment of the provided text.
+  rpc AnalyzeSentiment(AnalyzeSentimentRequest) returns (AnalyzeSentimentResponse) {
+    option (google.api.http) = { post: "/v1beta1/documents:analyzeSentiment" body: "*" };
+  }
+
+  // Finds named entities (currently proper names and common nouns) in the text
+  // along with entity types, salience, mentions for each entity, and
+  // other properties.
+  rpc AnalyzeEntities(AnalyzeEntitiesRequest) returns (AnalyzeEntitiesResponse) {
+    option (google.api.http) = { post: "/v1beta1/documents:analyzeEntities" body: "*" };
+  }
+
+  // Analyzes the syntax of the text and provides sentence boundaries and
+  // tokenization along with part of speech tags, dependency trees, and other
+  // properties.
+  rpc AnalyzeSyntax(AnalyzeSyntaxRequest) returns (AnalyzeSyntaxResponse) {
+    option (google.api.http) = { post: "/v1beta1/documents:analyzeSyntax" body: "*" };
+  }
+
+  // A convenience method that provides all the features that analyzeSentiment,
+  // analyzeEntities, and analyzeSyntax provide in one call.
+  rpc AnnotateText(AnnotateTextRequest) returns (AnnotateTextResponse) {
+    option (google.api.http) = { post: "/v1beta1/documents:annotateText" body: "*" };
+  }
+}
+
+// ################################################################ #
+//
+// Represents the input to API methods.
+message Document {
+  // The document types enum.
+  enum Type {
+    // The content type is not specified.
+    TYPE_UNSPECIFIED = 0;
+
+    // Plain text
+    PLAIN_TEXT = 1;
+
+    // HTML
+    HTML = 2;
+  }
+
+  // Required. If the type is not set or is `TYPE_UNSPECIFIED`,
+  // returns an `INVALID_ARGUMENT` error.
+  Type type = 1;
+
+  // The source of the document: a string containing the content or a
+  // Google Cloud Storage URI.
+  oneof source {
+    // The content of the input in string format.
+    string content = 2;
+
+    // The Google Cloud Storage URI where the file content is located.
+    // This URI must be of the form: gs://bucket_name/object_name. For more
+    // details, see https://cloud.google.com/storage/docs/reference-uris.
+    // NOTE: Cloud Storage object versioning is not supported.
+    string gcs_content_uri = 3;
+  }
+
+  // The language of the document (if not specified, the language is
+  // automatically detected). Both ISO and BCP-47 language codes are
+  // accepted.<br>
+  // [Language Support](https://cloud.google.com/natural-language/docs/languages)
+  // lists currently supported languages for each API method.
+  // If the language (either specified by the caller or automatically detected)
+  // is not supported by the called API method, an `INVALID_ARGUMENT` error
+  // is returned.
+  string language = 4;
+}
+
+// Represents a sentence in the input document.
+message Sentence {
+  // The sentence text.
+  TextSpan text = 1;
+
+  // For calls to [AnalyzeSentiment][] or if
+  // [AnnotateTextRequest.Features.extract_document_sentiment][google.cloud.language.v1beta1.AnnotateTextRequest.Features.extract_document_sentiment] is set to
+  // true, this field will contain the sentiment for the sentence.
+  Sentiment sentiment = 2;
+}
+
+// Represents a phrase in the text that is a known entity, such as
+// a person, an organization, or location. The API associates information, such
+// as salience and mentions, with entities.
+message Entity {
+  // The type of the entity.
+  enum Type {
+    // Unknown
+    UNKNOWN = 0;
+
+    // Person
+    PERSON = 1;
+
+    // Location
+    LOCATION = 2;
+
+    // Organization
+    ORGANIZATION = 3;
+
+    // Event
+    EVENT = 4;
+
+    // Work of art
+    WORK_OF_ART = 5;
+
+    // Consumer goods
+    CONSUMER_GOOD = 6;
+
+    // Other types
+    OTHER = 7;
+  }
+
+  // The representative name for the entity.
+  string name = 1;
+
+  // The entity type.
+  Type type = 2;
+
+  // Metadata associated with the entity.
+  //
+  // Currently, Wikipedia URLs and Knowledge Graph MIDs are provided, if
+  // available. The associated keys are "wikipedia_url" and "mid", respectively.
+  map<string, string> metadata = 3;
+
+  // The salience score associated with the entity in the [0, 1.0] range.
+  //
+  // The salience score for an entity provides information about the
+  // importance or centrality of that entity to the entire document text.
+  // Scores closer to 0 are less salient, while scores closer to 1.0 are highly
+  // salient.
+  float salience = 4;
+
+  // The mentions of this entity in the input document. The API currently
+  // supports proper noun mentions.
+  repeated EntityMention mentions = 5;
+}
+
+// Represents the smallest syntactic building block of the text.
+message Token {
+  // The token text.
+  TextSpan text = 1;
+
+  // Parts of speech tag for this token.
+  PartOfSpeech part_of_speech = 2;
+
+  // Dependency tree parse for this token.
+  DependencyEdge dependency_edge = 3;
+
+  // [Lemma](https://en.wikipedia.org/wiki/Lemma_%28morphology%29) of the token.
+  string lemma = 4;
+}
+
+// Represents the feeling associated with the entire text or entities in
+// the text.
+message Sentiment {
+  // DEPRECATED FIELD - This field is being deprecated in
+  // favor of score. Please refer to our documentation at
+  // https://cloud.google.com/natural-language/docs for more information.
+  float polarity = 1;
+
+  // A non-negative number in the [0, +inf) range, which represents
+  // the absolute magnitude of sentiment regardless of score (positive or
+  // negative).
+  float magnitude = 2;
+
+  // Sentiment score between -1.0 (negative sentiment) and 1.0
+  // (positive sentiment).
+  float score = 3;
+}
+
+// Represents part of speech information for a token.
+message PartOfSpeech {
+  // The part of speech tags enum.
+  enum Tag {
+    // Unknown
+    UNKNOWN = 0;
+
+    // Adjective
+    ADJ = 1;
+
+    // Adposition (preposition and postposition)
+    ADP = 2;
+
+    // Adverb
+    ADV = 3;
+
+    // Conjunction
+    CONJ = 4;
+
+    // Determiner
+    DET = 5;
+
+    // Noun (common and proper)
+    NOUN = 6;
+
+    // Cardinal number
+    NUM = 7;
+
+    // Pronoun
+    PRON = 8;
+
+    // Particle or other function word
+    PRT = 9;
+
+    // Punctuation
+    PUNCT = 10;
+
+    // Verb (all tenses and modes)
+    VERB = 11;
+
+    // Other: foreign words, typos, abbreviations
+    X = 12;
+
+    // Affix
+    AFFIX = 13;
+  }
+
+  // The characteristic of a verb that expresses time flow during an event.
+  enum Aspect {
+    // Aspect is not applicable in the analyzed language or is not predicted.
+    ASPECT_UNKNOWN = 0;
+
+    // Perfective
+    PERFECTIVE = 1;
+
+    // Imperfective
+    IMPERFECTIVE = 2;
+
+    // Progressive
+    PROGRESSIVE = 3;
+  }
+
+  // The grammatical function performed by a noun or pronoun in a phrase,
+  // clause, or sentence. In some languages, other parts of speech, such as
+  // adjective and determiner, take case inflection in agreement with the noun.
+  enum Case {
+    // Case is not applicable in the analyzed language or is not predicted.
+    CASE_UNKNOWN = 0;
+
+    // Accusative
+    ACCUSATIVE = 1;
+
+    // Adverbial
+    ADVERBIAL = 2;
+
+    // Complementive
+    COMPLEMENTIVE = 3;
+
+    // Dative
+    DATIVE = 4;
+
+    // Genitive
+    GENITIVE = 5;
+
+    // Instrumental
+    INSTRUMENTAL = 6;
+
+    // Locative
+    LOCATIVE = 7;
+
+    // Nominative
+    NOMINATIVE = 8;
+
+    // Oblique
+    OBLIQUE = 9;
+
+    // Partitive
+    PARTITIVE = 10;
+
+    // Prepositional
+    PREPOSITIONAL = 11;
+
+    // Reflexive
+    REFLEXIVE_CASE = 12;
+
+    // Relative
+    RELATIVE_CASE = 13;
+
+    // Vocative
+    VOCATIVE = 14;
+  }
+
+  // Depending on the language, Form can be categorizing different forms of
+  // verbs, adjectives, adverbs, etc. For example, categorizing inflected
+  // endings of verbs and adjectives or distinguishing between short and long
+  // forms of adjectives and participles
+  enum Form {
+    // Form is not applicable in the analyzed language or is not predicted.
+    FORM_UNKNOWN = 0;
+
+    // Adnomial
+    ADNOMIAL = 1;
+
+    // Auxiliary
+    AUXILIARY = 2;
+
+    // Complementizer
+    COMPLEMENTIZER = 3;
+
+    // Final ending
+    FINAL_ENDING = 4;
+
+    // Gerund
+    GERUND = 5;
+
+    // Realis
+    REALIS = 6;
+
+    // Irrealis
+    IRREALIS = 7;
+
+    // Short form
+    SHORT = 8;
+
+    // Long form
+    LONG = 9;
+
+    // Order form
+    ORDER = 10;
+
+    // Specific form
+    SPECIFIC = 11;
+  }
+
+  // Gender classes of nouns reflected in the behaviour of associated words.
+  enum Gender {
+    // Gender is not applicable in the analyzed language or is not predicted.
+    GENDER_UNKNOWN = 0;
+
+    // Feminine
+    FEMININE = 1;
+
+    // Masculine
+    MASCULINE = 2;
+
+    // Neuter
+    NEUTER = 3;
+  }
+
+  // The grammatical feature of verbs, used for showing modality and attitude.
+  enum Mood {
+    // Mood is not applicable in the analyzed language or is not predicted.
+    MOOD_UNKNOWN = 0;
+
+    // Conditional
+    CONDITIONAL_MOOD = 1;
+
+    // Imperative
+    IMPERATIVE = 2;
+
+    // Indicative
+    INDICATIVE = 3;
+
+    // Interrogative
+    INTERROGATIVE = 4;
+
+    // Jussive
+    JUSSIVE = 5;
+
+    // Subjunctive
+    SUBJUNCTIVE = 6;
+  }
+
+  // Count distinctions.
+  enum Number {
+    // Number is not applicable in the analyzed language or is not predicted.
+    NUMBER_UNKNOWN = 0;
+
+    // Singular
+    SINGULAR = 1;
+
+    // Plural
+    PLURAL = 2;
+
+    // Dual
+    DUAL = 3;
+  }
+
+  // The distinction between the speaker, second person, third person, etc.
+  enum Person {
+    // Person is not applicable in the analyzed language or is not predicted.
+    PERSON_UNKNOWN = 0;
+
+    // First
+    FIRST = 1;
+
+    // Second
+    SECOND = 2;
+
+    // Third
+    THIRD = 3;
+
+    // Reflexive
+    REFLEXIVE_PERSON = 4;
+  }
+
+  // This category shows if the token is part of a proper name.
+  enum Proper {
+    // Proper is not applicable in the analyzed language or is not predicted.
+    PROPER_UNKNOWN = 0;
+
+    // Proper
+    PROPER = 1;
+
+    // Not proper
+    NOT_PROPER = 2;
+  }
+
+  // Reciprocal features of a pronoun.
+  enum Reciprocity {
+    // Reciprocity is not applicable in the analyzed language or is not
+    // predicted.
+    RECIPROCITY_UNKNOWN = 0;
+
+    // Reciprocal
+    RECIPROCAL = 1;
+
+    // Non-reciprocal
+    NON_RECIPROCAL = 2;
+  }
+
+  // Time reference.
+  enum Tense {
+    // Tense is not applicable in the analyzed language or is not predicted.
+    TENSE_UNKNOWN = 0;
+
+    // Conditional
+    CONDITIONAL_TENSE = 1;
+
+    // Future
+    FUTURE = 2;
+
+    // Past
+    PAST = 3;
+
+    // Present
+    PRESENT = 4;
+
+    // Imperfect
+    IMPERFECT = 5;
+
+    // Pluperfect
+    PLUPERFECT = 6;
+  }
+
+  // The relationship between the action that a verb expresses and the
+  // participants identified by its arguments.
+  enum Voice {
+    // Voice is not applicable in the analyzed language or is not predicted.
+    VOICE_UNKNOWN = 0;
+
+    // Active
+    ACTIVE = 1;
+
+    // Causative
+    CAUSATIVE = 2;
+
+    // Passive
+    PASSIVE = 3;
+  }
+
+  // The part of speech tag.
+  Tag tag = 1;
+
+  // The grammatical aspect.
+  Aspect aspect = 2;
+
+  // The grammatical case.
+  Case case = 3;
+
+  // The grammatical form.
+  Form form = 4;
+
+  // The grammatical gender.
+  Gender gender = 5;
+
+  // The grammatical mood.
+  Mood mood = 6;
+
+  // The grammatical number.
+  Number number = 7;
+
+  // The grammatical person.
+  Person person = 8;
+
+  // The grammatical properness.
+  Proper proper = 9;
+
+  // The grammatical reciprocity.
+  Reciprocity reciprocity = 10;
+
+  // The grammatical tense.
+  Tense tense = 11;
+
+  // The grammatical voice.
+  Voice voice = 12;
+}
+
+// Represents dependency parse tree information for a token.
+message DependencyEdge {
+  // The parse label enum for the token.
+  enum Label {
+    // Unknown
+    UNKNOWN = 0;
+
+    // Abbreviation modifier
+    ABBREV = 1;
+
+    // Adjectival complement
+    ACOMP = 2;
+
+    // Adverbial clause modifier
+    ADVCL = 3;
+
+    // Adverbial modifier
+    ADVMOD = 4;
+
+    // Adjectival modifier of an NP
+    AMOD = 5;
+
+    // Appositional modifier of an NP
+    APPOS = 6;
+
+    // Attribute dependent of a copular verb
+    ATTR = 7;
+
+    // Auxiliary (non-main) verb
+    AUX = 8;
+
+    // Passive auxiliary
+    AUXPASS = 9;
+
+    // Coordinating conjunction
+    CC = 10;
+
+    // Clausal complement of a verb or adjective
+    CCOMP = 11;
+
+    // Conjunct
+    CONJ = 12;
+
+    // Clausal subject
+    CSUBJ = 13;
+
+    // Clausal passive subject
+    CSUBJPASS = 14;
+
+    // Dependency (unable to determine)
+    DEP = 15;
+
+    // Determiner
+    DET = 16;
+
+    // Discourse
+    DISCOURSE = 17;
+
+    // Direct object
+    DOBJ = 18;
+
+    // Expletive
+    EXPL = 19;
+
+    // Goes with (part of a word in a text not well edited)
+    GOESWITH = 20;
+
+    // Indirect object
+    IOBJ = 21;
+
+    // Marker (word introducing a subordinate clause)
+    MARK = 22;
+
+    // Multi-word expression
+    MWE = 23;
+
+    // Multi-word verbal expression
+    MWV = 24;
+
+    // Negation modifier
+    NEG = 25;
+
+    // Noun compound modifier
+    NN = 26;
+
+    // Noun phrase used as an adverbial modifier
+    NPADVMOD = 27;
+
+    // Nominal subject
+    NSUBJ = 28;
+
+    // Passive nominal subject
+    NSUBJPASS = 29;
+
+    // Numeric modifier of a noun
+    NUM = 30;
+
+    // Element of compound number
+    NUMBER = 31;
+
+    // Punctuation mark
+    P = 32;
+
+    // Parataxis relation
+    PARATAXIS = 33;
+
+    // Participial modifier
+    PARTMOD = 34;
+
+    // The complement of a preposition is a clause
+    PCOMP = 35;
+
+    // Object of a preposition
+    POBJ = 36;
+
+    // Possession modifier
+    POSS = 37;
+
+    // Postverbal negative particle
+    POSTNEG = 38;
+
+    // Predicate complement
+    PRECOMP = 39;
+
+    // Preconjunt
+    PRECONJ = 40;
+
+    // Predeterminer
+    PREDET = 41;
+
+    // Prefix
+    PREF = 42;
+
+    // Prepositional modifier
+    PREP = 43;
+
+    // The relationship between a verb and verbal morpheme
+    PRONL = 44;
+
+    // Particle
+    PRT = 45;
+
+    // Associative or possessive marker
+    PS = 46;
+
+    // Quantifier phrase modifier
+    QUANTMOD = 47;
+
+    // Relative clause modifier
+    RCMOD = 48;
+
+    // Complementizer in relative clause
+    RCMODREL = 49;
+
+    // Ellipsis without a preceding predicate
+    RDROP = 50;
+
+    // Referent
+    REF = 51;
+
+    // Remnant
+    REMNANT = 52;
+
+    // Reparandum
+    REPARANDUM = 53;
+
+    // Root
+    ROOT = 54;
+
+    // Suffix specifying a unit of number
+    SNUM = 55;
+
+    // Suffix
+    SUFF = 56;
+
+    // Temporal modifier
+    TMOD = 57;
+
+    // Topic marker
+    TOPIC = 58;
+
+    // Clause headed by an infinite form of the verb that modifies a noun
+    VMOD = 59;
+
+    // Vocative
+    VOCATIVE = 60;
+
+    // Open clausal complement
+    XCOMP = 61;
+
+    // Name suffix
+    SUFFIX = 62;
+
+    // Name title
+    TITLE = 63;
+
+    // Adverbial phrase modifier
+    ADVPHMOD = 64;
+
+    // Causative auxiliary
+    AUXCAUS = 65;
+
+    // Helper auxiliary
+    AUXVV = 66;
+
+    // Rentaishi (Prenominal modifier)
+    DTMOD = 67;
+
+    // Foreign words
+    FOREIGN = 68;
+
+    // Keyword
+    KW = 69;
+
+    // List for chains of comparable items
+    LIST = 70;
+
+    // Nominalized clause
+    NOMC = 71;
+
+    // Nominalized clausal subject
+    NOMCSUBJ = 72;
+
+    // Nominalized clausal passive
+    NOMCSUBJPASS = 73;
+
+    // Compound of numeric modifier
+    NUMC = 74;
+
+    // Copula
+    COP = 75;
+
+    // Dislocated relation (for fronted/topicalized elements)
+    DISLOCATED = 76;
+  }
+
+  // Represents the head of this token in the dependency tree.
+  // This is the index of the token which has an arc going to this token.
+  // The index is the position of the token in the array of tokens returned
+  // by the API method. If this token is a root token, then the
+  // `head_token_index` is its own index.
+  int32 head_token_index = 1;
+
+  // The parse label for the token.
+  Label label = 2;
+}
+
+// Represents a mention for an entity in the text. Currently, proper noun
+// mentions are supported.
+message EntityMention {
+  // The supported types of mentions.
+  enum Type {
+    // Unknown
+    TYPE_UNKNOWN = 0;
+
+    // Proper name
+    PROPER = 1;
+
+    // Common noun (or noun compound)
+    COMMON = 2;
+  }
+
+  // The mention text.
+  TextSpan text = 1;
+
+  // The type of the entity mention.
+  Type type = 2;
+}
+
+// Represents an output piece of text.
+message TextSpan {
+  // The content of the output text.
+  string content = 1;
+
+  // The API calculates the beginning offset of the content in the original
+  // document according to the [EncodingType][google.cloud.language.v1beta1.EncodingType] specified in the API request.
+  int32 begin_offset = 2;
+}
+
+// The sentiment analysis request message.
+message AnalyzeSentimentRequest {
+  // Input document.
+  Document document = 1;
+
+  // The encoding type used by the API to calculate sentence offsets for the
+  // sentence sentiment.
+  EncodingType encoding_type = 2;
+}
+
+// The sentiment analysis response message.
+message AnalyzeSentimentResponse {
+  // The overall sentiment of the input document.
+  Sentiment document_sentiment = 1;
+
+  // The language of the text, which will be the same as the language specified
+  // in the request or, if not specified, the automatically-detected language.
+  // See [Document.language][google.cloud.language.v1beta1.Document.language] field for more details.
+  string language = 2;
+
+  // The sentiment for all the sentences in the document.
+  repeated Sentence sentences = 3;
+}
+
+// The entity analysis request message.
+message AnalyzeEntitiesRequest {
+  // Input document.
+  Document document = 1;
+
+  // The encoding type used by the API to calculate offsets.
+  EncodingType encoding_type = 2;
+}
+
+// The entity analysis response message.
+message AnalyzeEntitiesResponse {
+  // The recognized entities in the input document.
+  repeated Entity entities = 1;
+
+  // The language of the text, which will be the same as the language specified
+  // in the request or, if not specified, the automatically-detected language.
+  // See [Document.language][google.cloud.language.v1beta1.Document.language] field for more details.
+  string language = 2;
+}
+
+// The syntax analysis request message.
+message AnalyzeSyntaxRequest {
+  // Input document.
+  Document document = 1;
+
+  // The encoding type used by the API to calculate offsets.
+  EncodingType encoding_type = 2;
+}
+
+// The syntax analysis response message.
+message AnalyzeSyntaxResponse {
+  // Sentences in the input document.
+  repeated Sentence sentences = 1;
+
+  // Tokens, along with their syntactic information, in the input document.
+  repeated Token tokens = 2;
+
+  // The language of the text, which will be the same as the language specified
+  // in the request or, if not specified, the automatically-detected language.
+  // See [Document.language][google.cloud.language.v1beta1.Document.language] field for more details.
+  string language = 3;
+}
+
+// The request message for the text annotation API, which can perform multiple
+// analysis types (sentiment, entities, and syntax) in one call.
+message AnnotateTextRequest {
+  // All available features for sentiment, syntax, and semantic analysis.
+  // Setting each one to true will enable that specific analysis for the input.
+  message Features {
+    // Extract syntax information.
+    bool extract_syntax = 1;
+
+    // Extract entities.
+    bool extract_entities = 2;
+
+    // Extract document-level sentiment.
+    bool extract_document_sentiment = 3;
+  }
+
+  // Input document.
+  Document document = 1;
+
+  // The enabled features.
+  Features features = 2;
+
+  // The encoding type used by the API to calculate offsets.
+  EncodingType encoding_type = 3;
+}
+
+// The text annotations response message.
+message AnnotateTextResponse {
+  // Sentences in the input document. Populated if the user enables
+  // [AnnotateTextRequest.Features.extract_syntax][google.cloud.language.v1beta1.AnnotateTextRequest.Features.extract_syntax].
+  repeated Sentence sentences = 1;
+
+  // Tokens, along with their syntactic information, in the input document.
+  // Populated if the user enables
+  // [AnnotateTextRequest.Features.extract_syntax][google.cloud.language.v1beta1.AnnotateTextRequest.Features.extract_syntax].
+  repeated Token tokens = 2;
+
+  // Entities, along with their semantic information, in the input document.
+  // Populated if the user enables
+  // [AnnotateTextRequest.Features.extract_entities][google.cloud.language.v1beta1.AnnotateTextRequest.Features.extract_entities].
+  repeated Entity entities = 3;
+
+  // The overall sentiment for the document. Populated if the user enables
+  // [AnnotateTextRequest.Features.extract_document_sentiment][google.cloud.language.v1beta1.AnnotateTextRequest.Features.extract_document_sentiment].
+  Sentiment document_sentiment = 4;
+
+  // The language of the text, which will be the same as the language specified
+  // in the request or, if not specified, the automatically-detected language.
+  // See [Document.language][google.cloud.language.v1beta1.Document.language] field for more details.
+  string language = 5;
+}
+
+// Represents the text encoding that the caller uses to process the output.
+// Providing an `EncodingType` is recommended because the API provides the
+// beginning offsets for various outputs, such as tokens and mentions, and
+// languages that natively use different text encodings may access offsets
+// differently.
+enum EncodingType {
+  // If `EncodingType` is not specified, encoding-dependent information (such as
+  // `begin_offset`) will be set at `-1`.
+  NONE = 0;
+
+  // Encoding-dependent information (such as `begin_offset`) is calculated based
+  // on the UTF-8 encoding of the input. C++ and Go are examples of languages
+  // that use this encoding natively.
+  UTF8 = 1;
+
+  // Encoding-dependent information (such as `begin_offset`) is calculated based
+  // on the UTF-16 encoding of the input. Java and Javascript are examples of
+  // languages that use this encoding natively.
+  UTF16 = 2;
+
+  // Encoding-dependent information (such as `begin_offset`) is calculated based
+  // on the UTF-32 encoding of the input. Python is an example of a language
+  // that uses this encoding natively.
+  UTF32 = 3;
+}
diff --git a/language/synth.metadata b/language/synth.metadata
index 88fc58cbfa27..5ebf26d28f73 100644
--- a/language/synth.metadata
+++ b/language/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:21:34.263272Z",
+  "updateTime": "2019-01-24T01:00:35.096241Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/language/synth.py b/language/synth.py
index 6abc66811b9c..d8acb69950e9 100644
--- a/language/synth.py
+++ b/language/synth.py
@@ -31,6 +31,7 @@
         version,
         config_path=f"/google/cloud/language/artman_language_{version}.yaml",
         artman_output_name=f"language-{version}",
+        include_protos=True,
     )
 
     s.move(library / f"google/cloud/language_{version}/proto")
diff --git a/logging/google/cloud/logging_v2/proto/http_request.proto b/logging/google/cloud/logging_v2/proto/http_request.proto
new file mode 100644
index 000000000000..21b1367ab8ca
--- /dev/null
+++ b/logging/google/cloud/logging_v2/proto/http_request.proto
@@ -0,0 +1,93 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.logging.type;
+
+import "google/api/annotations.proto";
+import "google/protobuf/duration.proto";
+
+option csharp_namespace = "Google.Cloud.Logging.Type";
+option go_package = "google.golang.org/genproto/googleapis/logging/type;ltype";
+option java_multiple_files = true;
+option java_outer_classname = "HttpRequestProto";
+option java_package = "com.google.logging.type";
+option php_namespace = "Google\\Cloud\\Logging\\Type";
+
+
+// A common proto for logging HTTP requests. Only contains semantics
+// defined by the HTTP specification. Product-specific logging
+// information MUST be defined in a separate message.
+message HttpRequest {
+  // The request method. Examples: `"GET"`, `"HEAD"`, `"PUT"`, `"POST"`.
+  string request_method = 1;
+
+  // The scheme (http, https), the host name, the path and the query
+  // portion of the URL that was requested.
+  // Example: `"http://example.com/some/info?color=red"`.
+  string request_url = 2;
+
+  // The size of the HTTP request message in bytes, including the request
+  // headers and the request body.
+  int64 request_size = 3;
+
+  // The response code indicating the status of response.
+  // Examples: 200, 404.
+  int32 status = 4;
+
+  // The size of the HTTP response message sent back to the client, in bytes,
+  // including the response headers and the response body.
+  int64 response_size = 5;
+
+  // The user agent sent by the client. Example:
+  // `"Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Q312461; .NET CLR 1.0.3705)"`.
+  string user_agent = 6;
+
+  // The IP address (IPv4 or IPv6) of the client that issued the HTTP
+  // request. Examples: `"192.168.1.1"`, `"FE80::0202:B3FF:FE1E:8329"`.
+  string remote_ip = 7;
+
+  // The IP address (IPv4 or IPv6) of the origin server that the request was
+  // sent to.
+  string server_ip = 13;
+
+  // The referer URL of the request, as defined in
+  // [HTTP/1.1 Header Field Definitions](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html).
+  string referer = 8;
+
+  // The request processing latency on the server, from the time the request was
+  // received until the response was sent.
+  google.protobuf.Duration latency = 14;
+
+  // Whether or not a cache lookup was attempted.
+  bool cache_lookup = 11;
+
+  // Whether or not an entity was served from cache
+  // (with or without validation).
+  bool cache_hit = 9;
+
+  // Whether or not the response was validated with the origin server before
+  // being served from cache. This field is only meaningful if `cache_hit` is
+  // True.
+  bool cache_validated_with_origin_server = 10;
+
+  // The number of HTTP response bytes inserted into cache. Set only when a
+  // cache fill was attempted.
+  int64 cache_fill_bytes = 12;
+
+  // Protocol used for the request. Examples: "HTTP/1.1", "HTTP/2", "websocket"
+  string protocol = 15;
+}
diff --git a/logging/google/cloud/logging_v2/proto/log_entry.proto b/logging/google/cloud/logging_v2/proto/log_entry.proto
new file mode 100644
index 000000000000..2f1530e23f69
--- /dev/null
+++ b/logging/google/cloud/logging_v2/proto/log_entry.proto
@@ -0,0 +1,193 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.logging.v2;
+
+import "google/api/annotations.proto";
+import "google/api/monitored_resource.proto";
+import "google/logging/type/http_request.proto";
+import "google/logging/type/log_severity.proto";
+import "google/protobuf/any.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+
+option cc_enable_arenas = true;
+option csharp_namespace = "Google.Cloud.Logging.V2";
+option go_package = "google.golang.org/genproto/googleapis/logging/v2;logging";
+option java_multiple_files = true;
+option java_outer_classname = "LogEntryProto";
+option java_package = "com.google.logging.v2";
+option php_namespace = "Google\\Cloud\\Logging\\V2";
+
+
+// An individual entry in a log.
+message LogEntry {
+  // Required. The resource name of the log to which this log entry belongs:
+  //
+  //     "projects/[PROJECT_ID]/logs/[LOG_ID]"
+  //     "organizations/[ORGANIZATION_ID]/logs/[LOG_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]/logs/[LOG_ID]"
+  //     "folders/[FOLDER_ID]/logs/[LOG_ID]"
+  //
+  //  A project number may optionally be used in place of PROJECT_ID. The
+  //  project number is translated to its corresponding PROJECT_ID internally
+  //  and the `log_name` field will contain PROJECT_ID in queries and exports.
+  //
+  // `[LOG_ID]` must be URL-encoded within `log_name`. Example:
+  // `"organizations/1234567890/logs/cloudresourcemanager.googleapis.com%2Factivity"`.
+  // `[LOG_ID]` must be less than 512 characters long and can only include the
+  // following characters: upper and lower case alphanumeric characters,
+  // forward-slash, underscore, hyphen, and period.
+  //
+  // For backward compatibility, if `log_name` begins with a forward-slash, such
+  // as `/projects/...`, then the log entry is ingested as usual but the
+  // forward-slash is removed. Listing the log entry will not show the leading
+  // slash and filtering for a log name with a leading slash will never return
+  // any results.
+  string log_name = 12;
+
+  // Required. The primary monitored resource associated with this log entry.
+  // Example: a log entry that reports a database error would be
+  // associated with the monitored resource designating the particular
+  // database that reported the error.
+  google.api.MonitoredResource resource = 8;
+
+  // Optional. The log entry payload, which can be one of multiple types.
+  oneof payload {
+    // The log entry payload, represented as a protocol buffer.  Some
+    // Google Cloud Platform services use this field for their log
+    // entry payloads.
+    google.protobuf.Any proto_payload = 2;
+
+    // The log entry payload, represented as a Unicode string (UTF-8).
+    string text_payload = 3;
+
+    // The log entry payload, represented as a structure that is
+    // expressed as a JSON object.
+    google.protobuf.Struct json_payload = 6;
+  }
+
+  // Optional. The time the event described by the log entry occurred.
+  // This time is used to compute the log entry's age and to enforce
+  // the logs retention period. If this field is omitted in a new log
+  // entry, then Logging assigns it the current time.
+  // Timestamps have nanosecond accuracy, but trailing zeros in the fractional
+  // seconds might be omitted when the timestamp is displayed.
+  //
+  // Incoming log entries should have timestamps that are no more than
+  // the [logs retention period](/logging/quotas) in the past,
+  // and no more than 24 hours in the future. Log entries outside those time
+  // boundaries will not be available when calling `entries.list`, but
+  // those log entries can still be exported with
+  // [LogSinks](/logging/docs/api/tasks/exporting-logs).
+  google.protobuf.Timestamp timestamp = 9;
+
+  // Output only. The time the log entry was received by Logging.
+  google.protobuf.Timestamp receive_timestamp = 24;
+
+  // Optional. The severity of the log entry. The default value is
+  // `LogSeverity.DEFAULT`.
+  google.logging.type.LogSeverity severity = 10;
+
+  // Optional. A unique identifier for the log entry. If you provide a value,
+  // then Logging considers other log entries in the same project,
+  // with the same `timestamp`, and with the same `insert_id` to be duplicates
+  // which can be removed.  If omitted in new log entries, then
+  // Logging assigns its own unique identifier. The `insert_id` is also used
+  // to order log entries that have the same `timestamp` value.
+  string insert_id = 4;
+
+  // Optional. Information about the HTTP request associated with this
+  // log entry, if applicable.
+  google.logging.type.HttpRequest http_request = 7;
+
+  // Optional. A set of user-defined (key, value) data that provides additional
+  // information about the log entry.
+  map<string, string> labels = 11;
+
+  // Output only. Additional metadata about the monitored resource.
+  // Only `k8s_container`, `k8s_pod`, and `k8s_node` MonitoredResources have
+  // this field populated.
+  google.api.MonitoredResourceMetadata metadata = 25;
+
+  // Optional. Information about an operation associated with the log entry, if
+  // applicable.
+  LogEntryOperation operation = 15;
+
+  // Optional. Resource name of the trace associated with the log entry, if any.
+  // If it contains a relative resource name, the name is assumed to be relative
+  // to `//tracing.googleapis.com`. Example:
+  // `projects/my-projectid/traces/06796866738c859f2f19b7cfb3214824`
+  string trace = 22;
+
+  // Optional. The span ID within the trace associated with the log entry.
+  // For Trace spans, this is the same format that the Trace
+  // API v2 uses: a 16-character hexadecimal encoding of an 8-byte array, such
+  // as <code>"000000000000004a"</code>.
+  string span_id = 27;
+
+  // Optional. The sampling decision of the trace associated with the log entry.
+  // True means that the trace resource name in the `trace` field was sampled
+  // for storage in a trace backend. False means that the trace was not sampled
+  // for storage when this log entry was written, or the sampling decision was
+  // unknown at the time. A non-sampled `trace` value is still useful as a
+  // request correlation identifier. The default is False.
+  bool trace_sampled = 30;
+
+  // Optional. Source code location information associated with the log entry,
+  // if any.
+  LogEntrySourceLocation source_location = 23;
+}
+
+// Additional information about a potentially long-running operation with which
+// a log entry is associated.
+message LogEntryOperation {
+  // Optional. An arbitrary operation identifier. Log entries with the
+  // same identifier are assumed to be part of the same operation.
+  string id = 1;
+
+  // Optional. An arbitrary producer identifier. The combination of
+  // `id` and `producer` must be globally unique.  Examples for `producer`:
+  // `"MyDivision.MyBigCompany.com"`, `"github.com/MyProject/MyApplication"`.
+  string producer = 2;
+
+  // Optional. Set this to True if this is the first log entry in the operation.
+  bool first = 3;
+
+  // Optional. Set this to True if this is the last log entry in the operation.
+  bool last = 4;
+}
+
+// Additional information about the source code location that produced the log
+// entry.
+message LogEntrySourceLocation {
+  // Optional. Source file name. Depending on the runtime environment, this
+  // might be a simple name or a fully-qualified name.
+  string file = 1;
+
+  // Optional. Line within the source file. 1-based; 0 indicates no line number
+  // available.
+  int64 line = 2;
+
+  // Optional. Human-readable name of the function or method being invoked, with
+  // optional context such as the class or package name. This information may be
+  // used in contexts such as the logs viewer, where a file and line number are
+  // less meaningful. The format can vary by language. For example:
+  // `qual.if.ied.Class.method` (Java), `dir/package.func` (Go), `function`
+  // (Python).
+  string function = 3;
+}
diff --git a/logging/google/cloud/logging_v2/proto/log_entry_pb2.py b/logging/google/cloud/logging_v2/proto/log_entry_pb2.py
index 3aa17006be30..8cba40a04d64 100644
--- a/logging/google/cloud/logging_v2/proto/log_entry_pb2.py
+++ b/logging/google/cloud/logging_v2/proto/log_entry_pb2.py
@@ -857,3 +857,4 @@
 DESCRIPTOR._options = None
 _LOGENTRY_LABELSENTRY._options = None
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/logging/google/cloud/logging_v2/proto/log_severity.proto b/logging/google/cloud/logging_v2/proto/log_severity.proto
new file mode 100644
index 000000000000..ccb08cacb445
--- /dev/null
+++ b/logging/google/cloud/logging_v2/proto/log_severity.proto
@@ -0,0 +1,73 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.logging.type;
+
+import "google/api/annotations.proto";
+
+option csharp_namespace = "Google.Cloud.Logging.Type";
+option go_package = "google.golang.org/genproto/googleapis/logging/type;ltype";
+option java_multiple_files = true;
+option java_outer_classname = "LogSeverityProto";
+option java_package = "com.google.logging.type";
+option php_namespace = "Google\\Cloud\\Logging\\Type";
+
+
+// The severity of the event described in a log entry, expressed as one of the
+// standard severity levels listed below.  For your reference, the levels are
+// assigned the listed numeric values. The effect of using numeric values other
+// than those listed is undefined.
+//
+// You can filter for log entries by severity.  For example, the following
+// filter expression will match log entries with severities `INFO`, `NOTICE`,
+// and `WARNING`:
+//
+//     severity > DEBUG AND severity <= WARNING
+//
+// If you are writing log entries, you should map other severity encodings to
+// one of these standard levels. For example, you might map all of Java's FINE,
+// FINER, and FINEST levels to `LogSeverity.DEBUG`. You can preserve the
+// original severity level in the log entry payload if you wish.
+enum LogSeverity {
+  // (0) The log entry has no assigned severity level.
+  DEFAULT = 0;
+
+  // (100) Debug or trace information.
+  DEBUG = 100;
+
+  // (200) Routine information, such as ongoing status or performance.
+  INFO = 200;
+
+  // (300) Normal but significant events, such as start up, shut down, or
+  // a configuration change.
+  NOTICE = 300;
+
+  // (400) Warning events might cause problems.
+  WARNING = 400;
+
+  // (500) Error events are likely to cause problems.
+  ERROR = 500;
+
+  // (600) Critical events cause more severe problems or outages.
+  CRITICAL = 600;
+
+  // (700) A person must take an action immediately.
+  ALERT = 700;
+
+  // (800) One or more systems are unusable.
+  EMERGENCY = 800;
+}
diff --git a/logging/google/cloud/logging_v2/proto/logging.proto b/logging/google/cloud/logging_v2/proto/logging.proto
new file mode 100644
index 000000000000..b1812e6f82d2
--- /dev/null
+++ b/logging/google/cloud/logging_v2/proto/logging.proto
@@ -0,0 +1,346 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.logging.v2;
+
+import "google/api/annotations.proto";
+import "google/api/monitored_resource.proto";
+import "google/logging/v2/log_entry.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option cc_enable_arenas = true;
+option csharp_namespace = "Google.Cloud.Logging.V2";
+option go_package = "google.golang.org/genproto/googleapis/logging/v2;logging";
+option java_multiple_files = true;
+option java_outer_classname = "LoggingProto";
+option java_package = "com.google.logging.v2";
+option php_namespace = "Google\\Cloud\\Logging\\V2";
+
+
+// Service for ingesting and querying logs.
+service LoggingServiceV2 {
+  // Deletes all the log entries in a log.
+  // The log reappears if it receives new entries.
+  // Log entries written shortly before the delete operation might not be
+  // deleted.
+  rpc DeleteLog(DeleteLogRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{log_name=projects/*/logs/*}"
+      additional_bindings {
+        delete: "/v2/{log_name=organizations/*/logs/*}"
+      }
+      additional_bindings {
+        delete: "/v2/{log_name=folders/*/logs/*}"
+      }
+      additional_bindings {
+        delete: "/v2/{log_name=billingAccounts/*/logs/*}"
+      }
+    };
+  }
+
+  // Writes log entries to Logging. This API method is the
+  // only way to send log entries to Logging. This method
+  // is used, directly or indirectly, by the Logging agent
+  // (fluentd) and all logging libraries configured to use Logging.
+  // A single request may contain log entries for a maximum of 1000
+  // different resources (projects, organizations, billing accounts or
+  // folders)
+  rpc WriteLogEntries(WriteLogEntriesRequest) returns (WriteLogEntriesResponse) {
+    option (google.api.http) = {
+      post: "/v2/entries:write"
+      body: "*"
+    };
+  }
+
+  // Lists log entries.  Use this method to retrieve log entries from
+  // Logging.  For ways to export log entries, see
+  // [Exporting Logs](/logging/docs/export).
+  rpc ListLogEntries(ListLogEntriesRequest) returns (ListLogEntriesResponse) {
+    option (google.api.http) = {
+      post: "/v2/entries:list"
+      body: "*"
+    };
+  }
+
+  // Lists the descriptors for monitored resource types used by Logging.
+  rpc ListMonitoredResourceDescriptors(ListMonitoredResourceDescriptorsRequest) returns (ListMonitoredResourceDescriptorsResponse) {
+    option (google.api.http) = {
+      get: "/v2/monitoredResourceDescriptors"
+    };
+  }
+
+  // Lists the logs in projects, organizations, folders, or billing accounts.
+  // Only logs that have entries are listed.
+  rpc ListLogs(ListLogsRequest) returns (ListLogsResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=*/*}/logs"
+      additional_bindings {
+        get: "/v2/{parent=projects/*}/logs"
+      }
+      additional_bindings {
+        get: "/v2/{parent=organizations/*}/logs"
+      }
+      additional_bindings {
+        get: "/v2/{parent=folders/*}/logs"
+      }
+      additional_bindings {
+        get: "/v2/{parent=billingAccounts/*}/logs"
+      }
+    };
+  }
+}
+
+// The parameters to DeleteLog.
+message DeleteLogRequest {
+  // Required. The resource name of the log to delete:
+  //
+  //     "projects/[PROJECT_ID]/logs/[LOG_ID]"
+  //     "organizations/[ORGANIZATION_ID]/logs/[LOG_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]/logs/[LOG_ID]"
+  //     "folders/[FOLDER_ID]/logs/[LOG_ID]"
+  //
+  // `[LOG_ID]` must be URL-encoded. For example,
+  // `"projects/my-project-id/logs/syslog"`,
+  // `"organizations/1234567890/logs/cloudresourcemanager.googleapis.com%2Factivity"`.
+  // For more information about log names, see
+  // [LogEntry][google.logging.v2.LogEntry].
+  string log_name = 1;
+}
+
+// The parameters to WriteLogEntries.
+message WriteLogEntriesRequest {
+  // Optional. A default log resource name that is assigned to all log entries
+  // in `entries` that do not specify a value for `log_name`:
+  //
+  //     "projects/[PROJECT_ID]/logs/[LOG_ID]"
+  //     "organizations/[ORGANIZATION_ID]/logs/[LOG_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]/logs/[LOG_ID]"
+  //     "folders/[FOLDER_ID]/logs/[LOG_ID]"
+  //
+  // `[LOG_ID]` must be URL-encoded. For example:
+  //
+  //     "projects/my-project-id/logs/syslog"
+  //     "organizations/1234567890/logs/cloudresourcemanager.googleapis.com%2Factivity"
+  //
+  // The permission <code>logging.logEntries.create</code> is needed on each
+  // project, organization, billing account, or folder that is receiving
+  // new log entries, whether the resource is specified in
+  // <code>logName</code> or in an individual log entry.
+  string log_name = 1;
+
+  // Optional. A default monitored resource object that is assigned to all log
+  // entries in `entries` that do not specify a value for `resource`. Example:
+  //
+  //     { "type": "gce_instance",
+  //       "labels": {
+  //         "zone": "us-central1-a", "instance_id": "00000000000000000000" }}
+  //
+  // See [LogEntry][google.logging.v2.LogEntry].
+  google.api.MonitoredResource resource = 2;
+
+  // Optional. Default labels that are added to the `labels` field of all log
+  // entries in `entries`. If a log entry already has a label with the same key
+  // as a label in this parameter, then the log entry's label is not changed.
+  // See [LogEntry][google.logging.v2.LogEntry].
+  map<string, string> labels = 3;
+
+  // Required. The log entries to send to Logging. The order of log
+  // entries in this list does not matter. Values supplied in this method's
+  // `log_name`, `resource`, and `labels` fields are copied into those log
+  // entries in this list that do not include values for their corresponding
+  // fields. For more information, see the
+  // [LogEntry][google.logging.v2.LogEntry] type.
+  //
+  // If the `timestamp` or `insert_id` fields are missing in log entries, then
+  // this method supplies the current time or a unique identifier, respectively.
+  // The supplied values are chosen so that, among the log entries that did not
+  // supply their own values, the entries earlier in the list will sort before
+  // the entries later in the list. See the `entries.list` method.
+  //
+  // Log entries with timestamps that are more than the
+  // [logs retention period](/logging/quota-policy) in the past or more than
+  // 24 hours in the future will not be available when calling `entries.list`.
+  // However, those log entries can still be exported with
+  // [LogSinks](/logging/docs/api/tasks/exporting-logs).
+  //
+  // To improve throughput and to avoid exceeding the
+  // [quota limit](/logging/quota-policy) for calls to `entries.write`,
+  // you should try to include several log entries in this list,
+  // rather than calling this method for each individual log entry.
+  repeated LogEntry entries = 4;
+
+  // Optional. Whether valid entries should be written even if some other
+  // entries fail due to INVALID_ARGUMENT or PERMISSION_DENIED errors. If any
+  // entry is not written, then the response status is the error associated
+  // with one of the failed entries and the response includes error details
+  // keyed by the entries' zero-based index in the `entries.write` method.
+  bool partial_success = 5;
+
+  // Optional. If true, the request should expect normal response, but the
+  // entries won't be persisted nor exported. Useful for checking whether the
+  // logging API endpoints are working properly before sending valuable data.
+  bool dry_run = 6;
+}
+
+// Result returned from WriteLogEntries.
+// empty
+message WriteLogEntriesResponse {
+
+}
+
+// Error details for WriteLogEntries with partial success.
+message WriteLogEntriesPartialErrors {
+  // When `WriteLogEntriesRequest.partial_success` is true, records the error
+  // status for entries that were not written due to a permanent error, keyed
+  // by the entry's zero-based index in `WriteLogEntriesRequest.entries`.
+  //
+  // Failed requests for which no entries are written will not include
+  // per-entry errors.
+  map<int32, google.rpc.Status> log_entry_errors = 1;
+}
+
+// The parameters to `ListLogEntries`.
+message ListLogEntriesRequest {
+  // Deprecated. Use `resource_names` instead.  One or more project identifiers
+  // or project numbers from which to retrieve log entries.  Example:
+  // `"my-project-1A"`. If present, these project identifiers are converted to
+  // resource name format and added to the list of resources in
+  // `resource_names`.
+  repeated string project_ids = 1 [deprecated = true];
+
+  // Required. Names of one or more parent resources from which to
+  // retrieve log entries:
+  //
+  //     "projects/[PROJECT_ID]"
+  //     "organizations/[ORGANIZATION_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]"
+  //     "folders/[FOLDER_ID]"
+  //
+  // Projects listed in the `project_ids` field are added to this list.
+  repeated string resource_names = 8;
+
+  // Optional. A filter that chooses which log entries to return.  See [Advanced
+  // Logs Filters](/logging/docs/view/advanced_filters).  Only log entries that
+  // match the filter are returned.  An empty filter matches all log entries in
+  // the resources listed in `resource_names`. Referencing a parent resource
+  // that is not listed in `resource_names` will cause the filter to return no
+  // results.
+  // The maximum length of the filter is 20000 characters.
+  string filter = 2;
+
+  // Optional. How the results should be sorted.  Presently, the only permitted
+  // values are `"timestamp asc"` (default) and `"timestamp desc"`. The first
+  // option returns entries in order of increasing values of
+  // `LogEntry.timestamp` (oldest first), and the second option returns entries
+  // in order of decreasing timestamps (newest first).  Entries with equal
+  // timestamps are returned in order of their `insert_id` values.
+  string order_by = 3;
+
+  // Optional. The maximum number of results to return from this request.
+  // Non-positive values are ignored.  The presence of `next_page_token` in the
+  // response indicates that more results might be available.
+  int32 page_size = 4;
+
+  // Optional. If present, then retrieve the next batch of results from the
+  // preceding call to this method.  `page_token` must be the value of
+  // `next_page_token` from the previous response.  The values of other method
+  // parameters should be identical to those in the previous call.
+  string page_token = 5;
+}
+
+// Result returned from `ListLogEntries`.
+message ListLogEntriesResponse {
+  // A list of log entries.  If `entries` is empty, `nextPageToken` may still be
+  // returned, indicating that more entries may exist.  See `nextPageToken` for
+  // more information.
+  repeated LogEntry entries = 1;
+
+  // If there might be more results than those appearing in this response, then
+  // `nextPageToken` is included.  To get the next set of results, call this
+  // method again using the value of `nextPageToken` as `pageToken`.
+  //
+  // If a value for `next_page_token` appears and the `entries` field is empty,
+  // it means that the search found no log entries so far but it did not have
+  // time to search all the possible log entries.  Retry the method with this
+  // value for `page_token` to continue the search.  Alternatively, consider
+  // speeding up the search by changing your filter to specify a single log name
+  // or resource type, or to narrow the time range of the search.
+  string next_page_token = 2;
+}
+
+// The parameters to ListMonitoredResourceDescriptors
+message ListMonitoredResourceDescriptorsRequest {
+  // Optional. The maximum number of results to return from this request.
+  // Non-positive values are ignored.  The presence of `nextPageToken` in the
+  // response indicates that more results might be available.
+  int32 page_size = 1;
+
+  // Optional. If present, then retrieve the next batch of results from the
+  // preceding call to this method.  `pageToken` must be the value of
+  // `nextPageToken` from the previous response.  The values of other method
+  // parameters should be identical to those in the previous call.
+  string page_token = 2;
+}
+
+// Result returned from ListMonitoredResourceDescriptors.
+message ListMonitoredResourceDescriptorsResponse {
+  // A list of resource descriptors.
+  repeated google.api.MonitoredResourceDescriptor resource_descriptors = 1;
+
+  // If there might be more results than those appearing in this response, then
+  // `nextPageToken` is included.  To get the next set of results, call this
+  // method again using the value of `nextPageToken` as `pageToken`.
+  string next_page_token = 2;
+}
+
+// The parameters to ListLogs.
+message ListLogsRequest {
+  // Required. The resource name that owns the logs:
+  //
+  //     "projects/[PROJECT_ID]"
+  //     "organizations/[ORGANIZATION_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]"
+  //     "folders/[FOLDER_ID]"
+  string parent = 1;
+
+  // Optional. The maximum number of results to return from this request.
+  // Non-positive values are ignored.  The presence of `nextPageToken` in the
+  // response indicates that more results might be available.
+  int32 page_size = 2;
+
+  // Optional. If present, then retrieve the next batch of results from the
+  // preceding call to this method.  `pageToken` must be the value of
+  // `nextPageToken` from the previous response.  The values of other method
+  // parameters should be identical to those in the previous call.
+  string page_token = 3;
+}
+
+// Result returned from ListLogs.
+message ListLogsResponse {
+  // A list of log names. For example,
+  // `"projects/my-project/syslog"` or
+  // `"organizations/123/cloudresourcemanager.googleapis.com%2Factivity"`.
+  repeated string log_names = 3;
+
+  // If there might be more results than those appearing in this response, then
+  // `nextPageToken` is included.  To get the next set of results, call this
+  // method again using the value of `nextPageToken` as `pageToken`.
+  string next_page_token = 2;
+}
diff --git a/logging/google/cloud/logging_v2/proto/logging_config.proto b/logging/google/cloud/logging_v2/proto/logging_config.proto
new file mode 100644
index 000000000000..8803ace8180e
--- /dev/null
+++ b/logging/google/cloud/logging_v2/proto/logging_config.proto
@@ -0,0 +1,633 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.logging.v2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option cc_enable_arenas = true;
+option csharp_namespace = "Google.Cloud.Logging.V2";
+option go_package = "google.golang.org/genproto/googleapis/logging/v2;logging";
+option java_multiple_files = true;
+option java_outer_classname = "LoggingConfigProto";
+option java_package = "com.google.logging.v2";
+option php_namespace = "Google\\Cloud\\Logging\\V2";
+
+
+// Service for configuring sinks used to export log entries out of
+// Logging.
+service ConfigServiceV2 {
+  // Lists sinks.
+  rpc ListSinks(ListSinksRequest) returns (ListSinksResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=*/*}/sinks"
+      additional_bindings {
+        get: "/v2/{parent=projects/*}/sinks"
+      }
+      additional_bindings {
+        get: "/v2/{parent=organizations/*}/sinks"
+      }
+      additional_bindings {
+        get: "/v2/{parent=folders/*}/sinks"
+      }
+      additional_bindings {
+        get: "/v2/{parent=billingAccounts/*}/sinks"
+      }
+    };
+  }
+
+  // Gets a sink.
+  rpc GetSink(GetSinkRequest) returns (LogSink) {
+    option (google.api.http) = {
+      get: "/v2/{sink_name=*/*/sinks/*}"
+      additional_bindings {
+        get: "/v2/{sink_name=projects/*/sinks/*}"
+      }
+      additional_bindings {
+        get: "/v2/{sink_name=organizations/*/sinks/*}"
+      }
+      additional_bindings {
+        get: "/v2/{sink_name=folders/*/sinks/*}"
+      }
+      additional_bindings {
+        get: "/v2/{sink_name=billingAccounts/*/sinks/*}"
+      }
+    };
+  }
+
+  // Creates a sink that exports specified log entries to a destination.  The
+  // export of newly-ingested log entries begins immediately, unless the sink's
+  // `writer_identity` is not permitted to write to the destination.  A sink can
+  // export log entries only from the resource owning the sink.
+  rpc CreateSink(CreateSinkRequest) returns (LogSink) {
+    option (google.api.http) = {
+      post: "/v2/{parent=*/*}/sinks"
+      body: "sink"
+      additional_bindings {
+        post: "/v2/{parent=projects/*}/sinks"
+        body: "sink"
+      }
+      additional_bindings {
+        post: "/v2/{parent=organizations/*}/sinks"
+        body: "sink"
+      }
+      additional_bindings {
+        post: "/v2/{parent=folders/*}/sinks"
+        body: "sink"
+      }
+      additional_bindings {
+        post: "/v2/{parent=billingAccounts/*}/sinks"
+        body: "sink"
+      }
+    };
+  }
+
+  // Updates a sink.  This method replaces the following fields in the existing
+  // sink with values from the new sink: `destination`, and `filter`.
+  // The updated sink might also have a new `writer_identity`; see the
+  // `unique_writer_identity` field.
+  rpc UpdateSink(UpdateSinkRequest) returns (LogSink) {
+    option (google.api.http) = {
+      put: "/v2/{sink_name=*/*/sinks/*}"
+      body: "sink"
+      additional_bindings {
+        put: "/v2/{sink_name=projects/*/sinks/*}"
+        body: "sink"
+      }
+      additional_bindings {
+        put: "/v2/{sink_name=organizations/*/sinks/*}"
+        body: "sink"
+      }
+      additional_bindings {
+        put: "/v2/{sink_name=folders/*/sinks/*}"
+        body: "sink"
+      }
+      additional_bindings {
+        put: "/v2/{sink_name=billingAccounts/*/sinks/*}"
+        body: "sink"
+      }
+      additional_bindings {
+        patch: "/v2/{sink_name=projects/*/sinks/*}"
+        body: "sink"
+      }
+      additional_bindings {
+        patch: "/v2/{sink_name=organizations/*/sinks/*}"
+        body: "sink"
+      }
+      additional_bindings {
+        patch: "/v2/{sink_name=folders/*/sinks/*}"
+        body: "sink"
+      }
+      additional_bindings {
+        patch: "/v2/{sink_name=billingAccounts/*/sinks/*}"
+        body: "sink"
+      }
+    };
+  }
+
+  // Deletes a sink. If the sink has a unique `writer_identity`, then that
+  // service account is also deleted.
+  rpc DeleteSink(DeleteSinkRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{sink_name=*/*/sinks/*}"
+      additional_bindings {
+        delete: "/v2/{sink_name=projects/*/sinks/*}"
+      }
+      additional_bindings {
+        delete: "/v2/{sink_name=organizations/*/sinks/*}"
+      }
+      additional_bindings {
+        delete: "/v2/{sink_name=folders/*/sinks/*}"
+      }
+      additional_bindings {
+        delete: "/v2/{sink_name=billingAccounts/*/sinks/*}"
+      }
+    };
+  }
+
+  // Lists all the exclusions in a parent resource.
+  rpc ListExclusions(ListExclusionsRequest) returns (ListExclusionsResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=*/*}/exclusions"
+      additional_bindings {
+        get: "/v2/{parent=projects/*}/exclusions"
+      }
+      additional_bindings {
+        get: "/v2/{parent=organizations/*}/exclusions"
+      }
+      additional_bindings {
+        get: "/v2/{parent=folders/*}/exclusions"
+      }
+      additional_bindings {
+        get: "/v2/{parent=billingAccounts/*}/exclusions"
+      }
+    };
+  }
+
+  // Gets the description of an exclusion.
+  rpc GetExclusion(GetExclusionRequest) returns (LogExclusion) {
+    option (google.api.http) = {
+      get: "/v2/{name=*/*/exclusions/*}"
+      additional_bindings {
+        get: "/v2/{name=projects/*/exclusions/*}"
+      }
+      additional_bindings {
+        get: "/v2/{name=organizations/*/exclusions/*}"
+      }
+      additional_bindings {
+        get: "/v2/{name=folders/*/exclusions/*}"
+      }
+      additional_bindings {
+        get: "/v2/{name=billingAccounts/*/exclusions/*}"
+      }
+    };
+  }
+
+  // Creates a new exclusion in a specified parent resource.
+  // Only log entries belonging to that resource can be excluded.
+  // You can have up to 10 exclusions in a resource.
+  rpc CreateExclusion(CreateExclusionRequest) returns (LogExclusion) {
+    option (google.api.http) = {
+      post: "/v2/{parent=*/*}/exclusions"
+      body: "exclusion"
+      additional_bindings {
+        post: "/v2/{parent=projects/*}/exclusions"
+        body: "exclusion"
+      }
+      additional_bindings {
+        post: "/v2/{parent=organizations/*}/exclusions"
+        body: "exclusion"
+      }
+      additional_bindings {
+        post: "/v2/{parent=folders/*}/exclusions"
+        body: "exclusion"
+      }
+      additional_bindings {
+        post: "/v2/{parent=billingAccounts/*}/exclusions"
+        body: "exclusion"
+      }
+    };
+  }
+
+  // Changes one or more properties of an existing exclusion.
+  rpc UpdateExclusion(UpdateExclusionRequest) returns (LogExclusion) {
+    option (google.api.http) = {
+      patch: "/v2/{name=*/*/exclusions/*}"
+      body: "exclusion"
+      additional_bindings {
+        patch: "/v2/{name=projects/*/exclusions/*}"
+        body: "exclusion"
+      }
+      additional_bindings {
+        patch: "/v2/{name=organizations/*/exclusions/*}"
+        body: "exclusion"
+      }
+      additional_bindings {
+        patch: "/v2/{name=folders/*/exclusions/*}"
+        body: "exclusion"
+      }
+      additional_bindings {
+        patch: "/v2/{name=billingAccounts/*/exclusions/*}"
+        body: "exclusion"
+      }
+    };
+  }
+
+  // Deletes an exclusion.
+  rpc DeleteExclusion(DeleteExclusionRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{name=*/*/exclusions/*}"
+      additional_bindings {
+        delete: "/v2/{name=projects/*/exclusions/*}"
+      }
+      additional_bindings {
+        delete: "/v2/{name=organizations/*/exclusions/*}"
+      }
+      additional_bindings {
+        delete: "/v2/{name=folders/*/exclusions/*}"
+      }
+      additional_bindings {
+        delete: "/v2/{name=billingAccounts/*/exclusions/*}"
+      }
+    };
+  }
+}
+
+// Describes a sink used to export log entries to one of the following
+// destinations in any project: a Cloud Storage bucket, a BigQuery dataset, or a
+// Cloud Pub/Sub topic.  A logs filter controls which log entries are
+// exported. The sink must be created within a project, organization, billing
+// account, or folder.
+message LogSink {
+  // Available log entry formats. Log entries can be written to
+  // Logging in either format and can be exported in either format.
+  // Version 2 is the preferred format.
+  enum VersionFormat {
+    // An unspecified format version that will default to V2.
+    VERSION_FORMAT_UNSPECIFIED = 0;
+
+    // `LogEntry` version 2 format.
+    V2 = 1;
+
+    // `LogEntry` version 1 format.
+    V1 = 2;
+  }
+
+  // Required. The client-assigned sink identifier, unique within the
+  // project. Example: `"my-syslog-errors-to-pubsub"`.  Sink identifiers are
+  // limited to 100 characters and can include only the following characters:
+  // upper and lower-case alphanumeric characters, underscores, hyphens, and
+  // periods.
+  string name = 1;
+
+  // Required. The export destination:
+  //
+  //     "storage.googleapis.com/[GCS_BUCKET]"
+  //     "bigquery.googleapis.com/projects/[PROJECT_ID]/datasets/[DATASET]"
+  //     "pubsub.googleapis.com/projects/[PROJECT_ID]/topics/[TOPIC_ID]"
+  //
+  // The sink's `writer_identity`, set when the sink is created, must
+  // have permission to write to the destination or else the log
+  // entries are not exported.  For more information, see
+  // [Exporting Logs With Sinks](/logging/docs/api/tasks/exporting-logs).
+  string destination = 3;
+
+  // Optional.
+  // An [advanced logs filter](/logging/docs/view/advanced_filters).  The only
+  // exported log entries are those that are in the resource owning the sink and
+  // that match the filter.  For example:
+  //
+  //     logName="projects/[PROJECT_ID]/logs/[LOG_ID]" AND severity>=ERROR
+  string filter = 5;
+
+  // Deprecated. The log entry format to use for this sink's exported log
+  // entries.  The v2 format is used by default and cannot be changed.
+  VersionFormat output_version_format = 6 [deprecated = true];
+
+  // Output only. An IAM identity&mdash;a service account or group&mdash;under
+  // which Logging writes the exported log entries to the sink's
+  // destination.  This field is set by
+  // [sinks.create](/logging/docs/api/reference/rest/v2/projects.sinks/create)
+  // and
+  // [sinks.update](/logging/docs/api/reference/rest/v2/projects.sinks/update),
+  // based on the setting of `unique_writer_identity` in those methods.
+  //
+  // Until you grant this identity write-access to the destination, log entry
+  // exports from this sink will fail. For more information,
+  // see [Granting access for a
+  // resource](/iam/docs/granting-roles-to-service-accounts#granting_access_to_a_service_account_for_a_resource).
+  // Consult the destination service's documentation to determine the
+  // appropriate IAM roles to assign to the identity.
+  string writer_identity = 8;
+
+  // Optional. This field applies only to sinks owned by organizations and
+  // folders. If the field is false, the default, only the logs owned by the
+  // sink's parent resource are available for export. If the field is true, then
+  // logs from all the projects, folders, and billing accounts contained in the
+  // sink's parent resource are also available for export. Whether a particular
+  // log entry from the children is exported depends on the sink's filter
+  // expression. For example, if this field is true, then the filter
+  // `resource.type=gce_instance` would export all Compute Engine VM instance
+  // log entries from all projects in the sink's parent. To only export entries
+  // from certain child projects, filter on the project part of the log name:
+  //
+  //     logName:("projects/test-project1/" OR "projects/test-project2/") AND
+  //     resource.type=gce_instance
+  bool include_children = 9;
+
+  // Deprecated. This field is ignored when creating or updating sinks.
+  google.protobuf.Timestamp start_time = 10 [deprecated = true];
+
+  // Deprecated. This field is ignored when creating or updating sinks.
+  google.protobuf.Timestamp end_time = 11 [deprecated = true];
+}
+
+// The parameters to `ListSinks`.
+message ListSinksRequest {
+  // Required. The parent resource whose sinks are to be listed:
+  //
+  //     "projects/[PROJECT_ID]"
+  //     "organizations/[ORGANIZATION_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]"
+  //     "folders/[FOLDER_ID]"
+  string parent = 1;
+
+  // Optional. If present, then retrieve the next batch of results from the
+  // preceding call to this method.  `pageToken` must be the value of
+  // `nextPageToken` from the previous response.  The values of other method
+  // parameters should be identical to those in the previous call.
+  string page_token = 2;
+
+  // Optional. The maximum number of results to return from this request.
+  // Non-positive values are ignored.  The presence of `nextPageToken` in the
+  // response indicates that more results might be available.
+  int32 page_size = 3;
+}
+
+// Result returned from `ListSinks`.
+message ListSinksResponse {
+  // A list of sinks.
+  repeated LogSink sinks = 1;
+
+  // If there might be more results than appear in this response, then
+  // `nextPageToken` is included.  To get the next set of results, call the same
+  // method again using the value of `nextPageToken` as `pageToken`.
+  string next_page_token = 2;
+}
+
+// The parameters to `GetSink`.
+message GetSinkRequest {
+  // Required. The resource name of the sink:
+  //
+  //     "projects/[PROJECT_ID]/sinks/[SINK_ID]"
+  //     "organizations/[ORGANIZATION_ID]/sinks/[SINK_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]/sinks/[SINK_ID]"
+  //     "folders/[FOLDER_ID]/sinks/[SINK_ID]"
+  //
+  // Example: `"projects/my-project-id/sinks/my-sink-id"`.
+  string sink_name = 1;
+}
+
+// The parameters to `CreateSink`.
+message CreateSinkRequest {
+  // Required. The resource in which to create the sink:
+  //
+  //     "projects/[PROJECT_ID]"
+  //     "organizations/[ORGANIZATION_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]"
+  //     "folders/[FOLDER_ID]"
+  //
+  // Examples: `"projects/my-logging-project"`, `"organizations/123456789"`.
+  string parent = 1;
+
+  // Required. The new sink, whose `name` parameter is a sink identifier that
+  // is not already in use.
+  LogSink sink = 2;
+
+  // Optional. Determines the kind of IAM identity returned as `writer_identity`
+  // in the new sink.  If this value is omitted or set to false, and if the
+  // sink's parent is a project, then the value returned as `writer_identity` is
+  // the same group or service account used by Logging before the
+  // addition of writer identities to this API. The sink's destination must be
+  // in the same project as the sink itself.
+  //
+  // If this field is set to true, or if the sink is owned by a non-project
+  // resource such as an organization, then the value of `writer_identity` will
+  // be a unique service account used only for exports from the new sink.  For
+  // more information, see `writer_identity` in [LogSink][google.logging.v2.LogSink].
+  bool unique_writer_identity = 3;
+}
+
+// The parameters to `UpdateSink`.
+message UpdateSinkRequest {
+  // Required. The full resource name of the sink to update, including the
+  // parent resource and the sink identifier:
+  //
+  //     "projects/[PROJECT_ID]/sinks/[SINK_ID]"
+  //     "organizations/[ORGANIZATION_ID]/sinks/[SINK_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]/sinks/[SINK_ID]"
+  //     "folders/[FOLDER_ID]/sinks/[SINK_ID]"
+  //
+  // Example: `"projects/my-project-id/sinks/my-sink-id"`.
+  string sink_name = 1;
+
+  // Required. The updated sink, whose name is the same identifier that appears
+  // as part of `sink_name`.
+  LogSink sink = 2;
+
+  // Optional. See
+  // [sinks.create](/logging/docs/api/reference/rest/v2/projects.sinks/create)
+  // for a description of this field.  When updating a sink, the effect of this
+  // field on the value of `writer_identity` in the updated sink depends on both
+  // the old and new values of this field:
+  //
+  // +   If the old and new values of this field are both false or both true,
+  //     then there is no change to the sink's `writer_identity`.
+  // +   If the old value is false and the new value is true, then
+  //     `writer_identity` is changed to a unique service account.
+  // +   It is an error if the old value is true and the new value is
+  //     set to false or defaulted to false.
+  bool unique_writer_identity = 3;
+
+  // Optional. Field mask that specifies the fields in `sink` that need
+  // an update. A sink field will be overwritten if, and only if, it is
+  // in the update mask.  `name` and output only fields cannot be updated.
+  //
+  // An empty updateMask is temporarily treated as using the following mask
+  // for backwards compatibility purposes:
+  //   destination,filter,includeChildren
+  // At some point in the future, behavior will be removed and specifying an
+  // empty updateMask will be an error.
+  //
+  // For a detailed `FieldMask` definition, see
+  // https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.FieldMask
+  //
+  // Example: `updateMask=filter`.
+  google.protobuf.FieldMask update_mask = 4;
+}
+
+// The parameters to `DeleteSink`.
+message DeleteSinkRequest {
+  // Required. The full resource name of the sink to delete, including the
+  // parent resource and the sink identifier:
+  //
+  //     "projects/[PROJECT_ID]/sinks/[SINK_ID]"
+  //     "organizations/[ORGANIZATION_ID]/sinks/[SINK_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]/sinks/[SINK_ID]"
+  //     "folders/[FOLDER_ID]/sinks/[SINK_ID]"
+  //
+  // Example: `"projects/my-project-id/sinks/my-sink-id"`.
+  string sink_name = 1;
+}
+
+// Specifies a set of log entries that are not to be stored in
+// Logging. If your project receives a large volume of logs, you might be able
+// to use exclusions to reduce your chargeable logs. Exclusions are processed
+// after log sinks, so you can export log entries before they are excluded.
+// Audit log entries and log entries from Amazon Web Services are never
+// excluded.
+message LogExclusion {
+  // Required. A client-assigned identifier, such as
+  // `"load-balancer-exclusion"`. Identifiers are limited to 100 characters and
+  // can include only letters, digits, underscores, hyphens, and periods.
+  string name = 1;
+
+  // Optional. A description of this exclusion.
+  string description = 2;
+
+  // Required.
+  // An [advanced logs filter](/logging/docs/view/advanced_filters)
+  // that matches the log entries to be excluded. By using the
+  // [sample function](/logging/docs/view/advanced_filters#sample),
+  // you can exclude less than 100% of the matching log entries.
+  // For example, the following filter matches 99% of low-severity log
+  // entries from load balancers:
+  //
+  // `"resource.type=http_load_balancer severity<ERROR sample(insertId, 0.99)"`
+  string filter = 3;
+
+  // Optional. If set to True, then this exclusion is disabled and it does not
+  // exclude any log entries. You can use
+  // [exclusions.patch](/logging/docs/reference/v2/rest/v2/projects.exclusions/patch)
+  // to change the value of this field.
+  bool disabled = 4;
+}
+
+// The parameters to `ListExclusions`.
+message ListExclusionsRequest {
+  // Required. The parent resource whose exclusions are to be listed.
+  //
+  //     "projects/[PROJECT_ID]"
+  //     "organizations/[ORGANIZATION_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]"
+  //     "folders/[FOLDER_ID]"
+  string parent = 1;
+
+  // Optional. If present, then retrieve the next batch of results from the
+  // preceding call to this method.  `pageToken` must be the value of
+  // `nextPageToken` from the previous response.  The values of other method
+  // parameters should be identical to those in the previous call.
+  string page_token = 2;
+
+  // Optional. The maximum number of results to return from this request.
+  // Non-positive values are ignored.  The presence of `nextPageToken` in the
+  // response indicates that more results might be available.
+  int32 page_size = 3;
+}
+
+// Result returned from `ListExclusions`.
+message ListExclusionsResponse {
+  // A list of exclusions.
+  repeated LogExclusion exclusions = 1;
+
+  // If there might be more results than appear in this response, then
+  // `nextPageToken` is included.  To get the next set of results, call the same
+  // method again using the value of `nextPageToken` as `pageToken`.
+  string next_page_token = 2;
+}
+
+// The parameters to `GetExclusion`.
+message GetExclusionRequest {
+  // Required. The resource name of an existing exclusion:
+  //
+  //     "projects/[PROJECT_ID]/exclusions/[EXCLUSION_ID]"
+  //     "organizations/[ORGANIZATION_ID]/exclusions/[EXCLUSION_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]/exclusions/[EXCLUSION_ID]"
+  //     "folders/[FOLDER_ID]/exclusions/[EXCLUSION_ID]"
+  //
+  // Example: `"projects/my-project-id/exclusions/my-exclusion-id"`.
+  string name = 1;
+}
+
+// The parameters to `CreateExclusion`.
+message CreateExclusionRequest {
+  // Required. The parent resource in which to create the exclusion:
+  //
+  //     "projects/[PROJECT_ID]"
+  //     "organizations/[ORGANIZATION_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]"
+  //     "folders/[FOLDER_ID]"
+  //
+  // Examples: `"projects/my-logging-project"`, `"organizations/123456789"`.
+  string parent = 1;
+
+  // Required. The new exclusion, whose `name` parameter is an exclusion name
+  // that is not already used in the parent resource.
+  LogExclusion exclusion = 2;
+}
+
+// The parameters to `UpdateExclusion`.
+message UpdateExclusionRequest {
+  // Required. The resource name of the exclusion to update:
+  //
+  //     "projects/[PROJECT_ID]/exclusions/[EXCLUSION_ID]"
+  //     "organizations/[ORGANIZATION_ID]/exclusions/[EXCLUSION_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]/exclusions/[EXCLUSION_ID]"
+  //     "folders/[FOLDER_ID]/exclusions/[EXCLUSION_ID]"
+  //
+  // Example: `"projects/my-project-id/exclusions/my-exclusion-id"`.
+  string name = 1;
+
+  // Required. New values for the existing exclusion. Only the fields specified
+  // in `update_mask` are relevant.
+  LogExclusion exclusion = 2;
+
+  // Required. A nonempty list of fields to change in the existing exclusion.
+  // New values for the fields are taken from the corresponding fields in the
+  // [LogExclusion][google.logging.v2.LogExclusion] included in this request. Fields not mentioned in
+  // `update_mask` are not changed and are ignored in the request.
+  //
+  // For example, to change the filter and description of an exclusion,
+  // specify an `update_mask` of `"filter,description"`.
+  google.protobuf.FieldMask update_mask = 3;
+}
+
+// The parameters to `DeleteExclusion`.
+message DeleteExclusionRequest {
+  // Required. The resource name of an existing exclusion to delete:
+  //
+  //     "projects/[PROJECT_ID]/exclusions/[EXCLUSION_ID]"
+  //     "organizations/[ORGANIZATION_ID]/exclusions/[EXCLUSION_ID]"
+  //     "billingAccounts/[BILLING_ACCOUNT_ID]/exclusions/[EXCLUSION_ID]"
+  //     "folders/[FOLDER_ID]/exclusions/[EXCLUSION_ID]"
+  //
+  // Example: `"projects/my-project-id/exclusions/my-exclusion-id"`.
+  string name = 1;
+}
diff --git a/logging/google/cloud/logging_v2/proto/logging_config_pb2.py b/logging/google/cloud/logging_v2/proto/logging_config_pb2.py
index d62ef9c95eec..5d6592292ecc 100644
--- a/logging/google/cloud/logging_v2/proto/logging_config_pb2.py
+++ b/logging/google/cloud/logging_v2/proto/logging_config_pb2.py
@@ -1699,3 +1699,4 @@
 DESCRIPTOR.services_by_name["ConfigServiceV2"] = _CONFIGSERVICEV2
 
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/logging/google/cloud/logging_v2/proto/logging_metrics.proto b/logging/google/cloud/logging_v2/proto/logging_metrics.proto
new file mode 100644
index 000000000000..229fb7ca5ccf
--- /dev/null
+++ b/logging/google/cloud/logging_v2/proto/logging_metrics.proto
@@ -0,0 +1,265 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.logging.v2;
+
+import "google/api/annotations.proto";
+import "google/api/distribution.proto";
+import "google/api/metric.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option cc_enable_arenas = true;
+option csharp_namespace = "Google.Cloud.Logging.V2";
+option go_package = "google.golang.org/genproto/googleapis/logging/v2;logging";
+option java_multiple_files = true;
+option java_outer_classname = "LoggingMetricsProto";
+option java_package = "com.google.logging.v2";
+option php_namespace = "Google\\Cloud\\Logging\\V2";
+
+
+// Service for configuring logs-based metrics.
+service MetricsServiceV2 {
+  // Lists logs-based metrics.
+  rpc ListLogMetrics(ListLogMetricsRequest) returns (ListLogMetricsResponse) {
+    option (google.api.http) = {
+      get: "/v2/{parent=projects/*}/metrics"
+    };
+  }
+
+  // Gets a logs-based metric.
+  rpc GetLogMetric(GetLogMetricRequest) returns (LogMetric) {
+    option (google.api.http) = {
+      get: "/v2/{metric_name=projects/*/metrics/*}"
+    };
+  }
+
+  // Creates a logs-based metric.
+  rpc CreateLogMetric(CreateLogMetricRequest) returns (LogMetric) {
+    option (google.api.http) = {
+      post: "/v2/{parent=projects/*}/metrics"
+      body: "metric"
+    };
+  }
+
+  // Creates or updates a logs-based metric.
+  rpc UpdateLogMetric(UpdateLogMetricRequest) returns (LogMetric) {
+    option (google.api.http) = {
+      put: "/v2/{metric_name=projects/*/metrics/*}"
+      body: "metric"
+    };
+  }
+
+  // Deletes a logs-based metric.
+  rpc DeleteLogMetric(DeleteLogMetricRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2/{metric_name=projects/*/metrics/*}"
+    };
+  }
+}
+
+// Describes a logs-based metric.  The value of the metric is the
+// number of log entries that match a logs filter in a given time interval.
+//
+// Logs-based metric can also be used to extract values from logs and create a
+// a distribution of the values. The distribution records the statistics of the
+// extracted values along with an optional histogram of the values as specified
+// by the bucket options.
+message LogMetric {
+  // Logging API version.
+  enum ApiVersion {
+    // Logging API v2.
+    V2 = 0;
+
+    // Logging API v1.
+    V1 = 1;
+  }
+
+  // Required. The client-assigned metric identifier.
+  // Examples: `"error_count"`, `"nginx/requests"`.
+  //
+  // Metric identifiers are limited to 100 characters and can include
+  // only the following characters: `A-Z`, `a-z`, `0-9`, and the
+  // special characters `_-.,+!*',()%/`.  The forward-slash character
+  // (`/`) denotes a hierarchy of name pieces, and it cannot be the
+  // first character of the name.
+  //
+  // The metric identifier in this field must not be
+  // [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding).
+  // However, when the metric identifier appears as the `[METRIC_ID]`
+  // part of a `metric_name` API parameter, then the metric identifier
+  // must be URL-encoded. Example:
+  // `"projects/my-project/metrics/nginx%2Frequests"`.
+  string name = 1;
+
+  // Optional. A description of this metric, which is used in documentation.
+  string description = 2;
+
+  // Required. An [advanced logs filter](/logging/docs/view/advanced_filters)
+  // which is used to match log entries.
+  // Example:
+  //
+  //     "resource.type=gae_app AND severity>=ERROR"
+  //
+  // The maximum length of the filter is 20000 characters.
+  string filter = 3;
+
+  // Optional. The metric descriptor associated with the logs-based metric.
+  // If unspecified, it uses a default metric descriptor with a DELTA metric
+  // kind, INT64 value type, with no labels and a unit of "1". Such a metric
+  // counts the number of log entries matching the `filter` expression.
+  //
+  // The `name`, `type`, and `description` fields in the `metric_descriptor`
+  // are output only, and is constructed using the `name` and `description`
+  // field in the LogMetric.
+  //
+  // To create a logs-based metric that records a distribution of log values, a
+  // DELTA metric kind with a DISTRIBUTION value type must be used along with
+  // a `value_extractor` expression in the LogMetric.
+  //
+  // Each label in the metric descriptor must have a matching label
+  // name as the key and an extractor expression as the value in the
+  // `label_extractors` map.
+  //
+  // The `metric_kind` and `value_type` fields in the `metric_descriptor` cannot
+  // be updated once initially configured. New labels can be added in the
+  // `metric_descriptor`, but existing labels cannot be modified except for
+  // their description.
+  google.api.MetricDescriptor metric_descriptor = 5;
+
+  // Optional. A `value_extractor` is required when using a distribution
+  // logs-based metric to extract the values to record from a log entry.
+  // Two functions are supported for value extraction: `EXTRACT(field)` or
+  // `REGEXP_EXTRACT(field, regex)`. The argument are:
+  //   1. field: The name of the log entry field from which the value is to be
+  //      extracted.
+  //   2. regex: A regular expression using the Google RE2 syntax
+  //      (https://github.com/google/re2/wiki/Syntax) with a single capture
+  //      group to extract data from the specified log entry field. The value
+  //      of the field is converted to a string before applying the regex.
+  //      It is an error to specify a regex that does not include exactly one
+  //      capture group.
+  //
+  // The result of the extraction must be convertible to a double type, as the
+  // distribution always records double values. If either the extraction or
+  // the conversion to double fails, then those values are not recorded in the
+  // distribution.
+  //
+  // Example: `REGEXP_EXTRACT(jsonPayload.request, ".*quantity=(\d+).*")`
+  string value_extractor = 6;
+
+  // Optional. A map from a label key string to an extractor expression which is
+  // used to extract data from a log entry field and assign as the label value.
+  // Each label key specified in the LabelDescriptor must have an associated
+  // extractor expression in this map. The syntax of the extractor expression
+  // is the same as for the `value_extractor` field.
+  //
+  // The extracted value is converted to the type defined in the label
+  // descriptor. If the either the extraction or the type conversion fails,
+  // the label will have a default value. The default value for a string
+  // label is an empty string, for an integer label its 0, and for a boolean
+  // label its `false`.
+  //
+  // Note that there are upper bounds on the maximum number of labels and the
+  // number of active time series that are allowed in a project.
+  map<string, string> label_extractors = 7;
+
+  // Optional. The `bucket_options` are required when the logs-based metric is
+  // using a DISTRIBUTION value type and it describes the bucket boundaries
+  // used to create a histogram of the extracted values.
+  google.api.Distribution.BucketOptions bucket_options = 8;
+
+  // Deprecated. The API version that created or updated this metric.
+  // The v2 format is used by default and cannot be changed.
+  ApiVersion version = 4 [deprecated = true];
+}
+
+// The parameters to ListLogMetrics.
+message ListLogMetricsRequest {
+  // Required. The name of the project containing the metrics:
+  //
+  //     "projects/[PROJECT_ID]"
+  string parent = 1;
+
+  // Optional. If present, then retrieve the next batch of results from the
+  // preceding call to this method.  `pageToken` must be the value of
+  // `nextPageToken` from the previous response.  The values of other method
+  // parameters should be identical to those in the previous call.
+  string page_token = 2;
+
+  // Optional. The maximum number of results to return from this request.
+  // Non-positive values are ignored.  The presence of `nextPageToken` in the
+  // response indicates that more results might be available.
+  int32 page_size = 3;
+}
+
+// Result returned from ListLogMetrics.
+message ListLogMetricsResponse {
+  // A list of logs-based metrics.
+  repeated LogMetric metrics = 1;
+
+  // If there might be more results than appear in this response, then
+  // `nextPageToken` is included.  To get the next set of results, call this
+  // method again using the value of `nextPageToken` as `pageToken`.
+  string next_page_token = 2;
+}
+
+// The parameters to GetLogMetric.
+message GetLogMetricRequest {
+  // The resource name of the desired metric:
+  //
+  //     "projects/[PROJECT_ID]/metrics/[METRIC_ID]"
+  string metric_name = 1;
+}
+
+// The parameters to CreateLogMetric.
+message CreateLogMetricRequest {
+  // The resource name of the project in which to create the metric:
+  //
+  //     "projects/[PROJECT_ID]"
+  //
+  // The new metric must be provided in the request.
+  string parent = 1;
+
+  // The new logs-based metric, which must not have an identifier that
+  // already exists.
+  LogMetric metric = 2;
+}
+
+// The parameters to UpdateLogMetric.
+message UpdateLogMetricRequest {
+  // The resource name of the metric to update:
+  //
+  //     "projects/[PROJECT_ID]/metrics/[METRIC_ID]"
+  //
+  // The updated metric must be provided in the request and it's
+  // `name` field must be the same as `[METRIC_ID]` If the metric
+  // does not exist in `[PROJECT_ID]`, then a new metric is created.
+  string metric_name = 1;
+
+  // The updated metric.
+  LogMetric metric = 2;
+}
+
+// The parameters to DeleteLogMetric.
+message DeleteLogMetricRequest {
+  // The resource name of the metric to delete:
+  //
+  //     "projects/[PROJECT_ID]/metrics/[METRIC_ID]"
+  string metric_name = 1;
+}
diff --git a/logging/google/cloud/logging_v2/proto/logging_metrics_pb2.py b/logging/google/cloud/logging_v2/proto/logging_metrics_pb2.py
index 54dc8f703c20..af0e78dd36ad 100644
--- a/logging/google/cloud/logging_v2/proto/logging_metrics_pb2.py
+++ b/logging/google/cloud/logging_v2/proto/logging_metrics_pb2.py
@@ -963,3 +963,4 @@
 DESCRIPTOR.services_by_name["MetricsServiceV2"] = _METRICSSERVICEV2
 
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/logging/google/cloud/logging_v2/proto/logging_pb2.py b/logging/google/cloud/logging_v2/proto/logging_pb2.py
index a37710bcf382..585f8f85624f 100644
--- a/logging/google/cloud/logging_v2/proto/logging_pb2.py
+++ b/logging/google/cloud/logging_v2/proto/logging_pb2.py
@@ -1304,3 +1304,4 @@
 DESCRIPTOR.services_by_name["LoggingServiceV2"] = _LOGGINGSERVICEV2
 
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/logging/synth.py b/logging/synth.py
index 922d805e9b2c..c24382ce4d72 100644
--- a/logging/synth.py
+++ b/logging/synth.py
@@ -27,6 +27,7 @@
     "v2",
     config_path="/google/logging/artman_logging.yaml",
     artman_output_name="logging-v2",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/logging_v2/proto")
diff --git a/monitoring/google/cloud/monitoring_v3/proto/alert.proto b/monitoring/google/cloud/monitoring_v3/proto/alert.proto
new file mode 100644
index 000000000000..1e22e61c7941
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/alert.proto
@@ -0,0 +1,344 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/annotations.proto";
+import "google/monitoring/v3/common.proto";
+import "google/monitoring/v3/mutation_record.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/wrappers.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "AlertProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// A description of the conditions under which some aspect of your system is
+// considered to be "unhealthy" and the ways to notify people or services about
+// this state. For an overview of alert policies, see
+// [Introduction to Alerting](/monitoring/alerts/).
+message AlertPolicy {
+  // A content string and a MIME type that describes the content string's
+  // format.
+  message Documentation {
+    // The text of the documentation, interpreted according to `mime_type`.
+    // The content may not exceed 8,192 Unicode characters and may not exceed
+    // more than 10,240 bytes when encoded in UTF-8 format, whichever is
+    // smaller.
+    string content = 1;
+
+    // The format of the `content` field. Presently, only the value
+    // `"text/markdown"` is supported. See
+    // [Markdown](https://en.wikipedia.org/wiki/Markdown) for more information.
+    string mime_type = 2;
+  }
+
+  // A condition is a true/false test that determines when an alerting policy
+  // should open an incident. If a condition evaluates to true, it signifies
+  // that something is wrong.
+  message Condition {
+    // Specifies how many time series must fail a predicate to trigger a
+    // condition. If not specified, then a `{count: 1}` trigger is used.
+    message Trigger {
+      // A type of trigger.
+      oneof type {
+        // The absolute number of time series that must fail
+        // the predicate for the condition to be triggered.
+        int32 count = 1;
+
+        // The percentage of time series that must fail the
+        // predicate for the condition to be triggered.
+        double percent = 2;
+      }
+    }
+
+    // A condition type that compares a collection of time series
+    // against a threshold.
+    message MetricThreshold {
+      // A [filter](/monitoring/api/v3/filters) that
+      // identifies which time series should be compared with the threshold.
+      //
+      // The filter is similar to the one that is specified in the
+      // [`MetricService.ListTimeSeries`
+      // request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list) (that
+      // call is useful to verify the time series that will be retrieved /
+      // processed) and must specify the metric type and optionally may contain
+      // restrictions on resource type, resource labels, and metric labels.
+      // This field may not exceed 2048 Unicode characters in length.
+      string filter = 2;
+
+      // Specifies the alignment of data points in individual time series as
+      // well as how to combine the retrieved time series together (such as
+      // when aggregating multiple streams on each resource to a single
+      // stream for each resource or when aggregating streams across all
+      // members of a group of resrouces). Multiple aggregations
+      // are applied in the order specified.
+      //
+      // This field is similar to the one in the
+      // [`MetricService.ListTimeSeries` request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list).
+      // It is advisable to use the `ListTimeSeries` method when debugging this field.
+      repeated Aggregation aggregations = 8;
+
+      // A [filter](/monitoring/api/v3/filters) that identifies a time
+      // series that should be used as the denominator of a ratio that will be
+      // compared with the threshold. If a `denominator_filter` is specified,
+      // the time series specified by the `filter` field will be used as the
+      // numerator.
+      //
+      // The filter is similar to the one that is specified in the
+      // [`MetricService.ListTimeSeries`
+      // request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list) (that
+      // call is useful to verify the time series that will be retrieved /
+      // processed) and must specify the metric type and optionally may contain
+      // restrictions on resource type, resource labels, and metric labels.
+      // This field may not exceed 2048 Unicode characters in length.
+      string denominator_filter = 9;
+
+      // Specifies the alignment of data points in individual time series
+      // selected by `denominatorFilter` as
+      // well as how to combine the retrieved time series together (such as
+      // when aggregating multiple streams on each resource to a single
+      // stream for each resource or when aggregating streams across all
+      // members of a group of resources).
+      //
+      // When computing ratios, the `aggregations` and
+      // `denominator_aggregations` fields must use the same alignment period
+      // and produce time series that have the same periodicity and labels.
+      //
+      // This field is similar to the one in the
+      // [`MetricService.ListTimeSeries`
+      // request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list). It
+      // is advisable to use the `ListTimeSeries` method when debugging this
+      // field.
+      repeated Aggregation denominator_aggregations = 10;
+
+      // The comparison to apply between the time series (indicated by `filter`
+      // and `aggregation`) and the threshold (indicated by `threshold_value`).
+      // The comparison is applied on each time series, with the time series
+      // on the left-hand side and the threshold on the right-hand side.
+      //
+      // Only `COMPARISON_LT` and `COMPARISON_GT` are supported currently.
+      ComparisonType comparison = 4;
+
+      // A value against which to compare the time series.
+      double threshold_value = 5;
+
+      // The amount of time that a time series must violate the
+      // threshold to be considered failing. Currently, only values
+      // that are a multiple of a minute--e.g., 0, 60, 120, or 300
+      // seconds--are supported. If an invalid value is given, an
+      // error will be returned. When choosing a duration, it is useful to
+      // keep in mind the frequency of the underlying time series data
+      // (which may also be affected by any alignments specified in the
+      // `aggregations` field); a good duration is long enough so that a single
+      // outlier does not generate spurious alerts, but short enough that
+      // unhealthy states are detected and alerted on quickly.
+      google.protobuf.Duration duration = 6;
+
+      // The number/percent of time series for which the comparison must hold
+      // in order for the condition to trigger. If unspecified, then the
+      // condition will trigger if the comparison is true for any of the
+      // time series that have been identified by `filter` and `aggregations`,
+      // or by the ratio, if `denominator_filter` and `denominator_aggregations`
+      // are specified.
+      Trigger trigger = 7;
+    }
+
+    // A condition type that checks that monitored resources
+    // are reporting data. The configuration defines a metric and
+    // a set of monitored resources. The predicate is considered in violation
+    // when a time series for the specified metric of a monitored
+    // resource does not include any data in the specified `duration`.
+    message MetricAbsence {
+      // A [filter](/monitoring/api/v3/filters) that
+      // identifies which time series should be compared with the threshold.
+      //
+      // The filter is similar to the one that is specified in the
+      // [`MetricService.ListTimeSeries`
+      // request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list) (that
+      // call is useful to verify the time series that will be retrieved /
+      // processed) and must specify the metric type and optionally may contain
+      // restrictions on resource type, resource labels, and metric labels.
+      // This field may not exceed 2048 Unicode characters in length.
+      string filter = 1;
+
+      // Specifies the alignment of data points in individual time series as
+      // well as how to combine the retrieved time series together (such as
+      // when aggregating multiple streams on each resource to a single
+      // stream for each resource or when aggregating streams across all
+      // members of a group of resrouces). Multiple aggregations
+      // are applied in the order specified.
+      //
+      // This field is similar to the
+      // one in the [`MetricService.ListTimeSeries` request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list).
+      // It is advisable to use the `ListTimeSeries` method when debugging this field.
+      repeated Aggregation aggregations = 5;
+
+      // The amount of time that a time series must fail to report new
+      // data to be considered failing. Currently, only values that
+      // are a multiple of a minute--e.g.  60, 120, or 300
+      // seconds--are supported. If an invalid value is given, an
+      // error will be returned. The `Duration.nanos` field is
+      // ignored.
+      google.protobuf.Duration duration = 2;
+
+      // The number/percent of time series for which the comparison must hold
+      // in order for the condition to trigger. If unspecified, then the
+      // condition will trigger if the comparison is true for any of the
+      // time series that have been identified by `filter` and `aggregations`.
+      Trigger trigger = 3;
+    }
+
+    // Required if the condition exists. The unique resource name for this
+    // condition. Its syntax is:
+    //
+    //     projects/[PROJECT_ID]/alertPolicies/[POLICY_ID]/conditions/[CONDITION_ID]
+    //
+    // `[CONDITION_ID]` is assigned by Stackdriver Monitoring when the
+    // condition is created as part of a new or updated alerting policy.
+    //
+    // When calling the
+    // [alertPolicies.create][google.monitoring.v3.AlertPolicyService.CreateAlertPolicy]
+    // method, do not include the `name` field in the conditions of the
+    // requested alerting policy. Stackdriver Monitoring creates the
+    // condition identifiers and includes them in the new policy.
+    //
+    // When calling the
+    // [alertPolicies.update][google.monitoring.v3.AlertPolicyService.UpdateAlertPolicy]
+    // method to update a policy, including a condition `name` causes the
+    // existing condition to be updated. Conditions without names are added to
+    // the updated policy. Existing conditions are deleted if they are not
+    // updated.
+    //
+    // Best practice is to preserve `[CONDITION_ID]` if you make only small
+    // changes, such as those to condition thresholds, durations, or trigger
+    // values.  Otherwise, treat the change as a new condition and let the
+    // existing condition be deleted.
+    string name = 12;
+
+    // A short name or phrase used to identify the condition in dashboards,
+    // notifications, and incidents. To avoid confusion, don't use the same
+    // display name for multiple conditions in the same policy.
+    string display_name = 6;
+
+    // Only one of the following condition types will be specified.
+    oneof condition {
+      // A condition that compares a time series against a threshold.
+      MetricThreshold condition_threshold = 1;
+
+      // A condition that checks that a time series continues to
+      // receive new data points.
+      MetricAbsence condition_absent = 2;
+    }
+  }
+
+  // Operators for combining conditions.
+  enum ConditionCombinerType {
+    // An unspecified combiner.
+    COMBINE_UNSPECIFIED = 0;
+
+    // Combine conditions using the logical `AND` operator. An
+    // incident is created only if all conditions are met
+    // simultaneously. This combiner is satisfied if all conditions are
+    // met, even if they are met on completely different resources.
+    AND = 1;
+
+    // Combine conditions using the logical `OR` operator. An incident
+    // is created if any of the listed conditions is met.
+    OR = 2;
+
+    // Combine conditions using logical `AND` operator, but unlike the regular
+    // `AND` option, an incident is created only if all conditions are met
+    // simultaneously on at least one resource.
+    AND_WITH_MATCHING_RESOURCE = 3;
+  }
+
+  // Required if the policy exists. The resource name for this policy. The
+  // syntax is:
+  //
+  //     projects/[PROJECT_ID]/alertPolicies/[ALERT_POLICY_ID]
+  //
+  // `[ALERT_POLICY_ID]` is assigned by Stackdriver Monitoring when the policy
+  // is created.  When calling the
+  // [alertPolicies.create][google.monitoring.v3.AlertPolicyService.CreateAlertPolicy]
+  // method, do not include the `name` field in the alerting policy passed as
+  // part of the request.
+  string name = 1;
+
+  // A short name or phrase used to identify the policy in dashboards,
+  // notifications, and incidents. To avoid confusion, don't use the same
+  // display name for multiple policies in the same project. The name is
+  // limited to 512 Unicode characters.
+  string display_name = 2;
+
+  // Documentation that is included with notifications and incidents related to
+  // this policy. Best practice is for the documentation to include information
+  // to help responders understand, mitigate, escalate, and correct the
+  // underlying problems detected by the alerting policy. Notification channels
+  // that have limited capacity might not show this documentation.
+  Documentation documentation = 13;
+
+  // User-supplied key/value data to be used for organizing and
+  // identifying the `AlertPolicy` objects.
+  //
+  // The field can contain up to 64 entries. Each key and value is limited to
+  // 63 Unicode characters or 128 bytes, whichever is smaller. Labels and
+  // values can contain only lowercase letters, numerals, underscores, and
+  // dashes. Keys must begin with a letter.
+  map<string, string> user_labels = 16;
+
+  // A list of conditions for the policy. The conditions are combined by AND or
+  // OR according to the `combiner` field. If the combined conditions evaluate
+  // to true, then an incident is created. A policy can have from one to six
+  // conditions.
+  repeated Condition conditions = 12;
+
+  // How to combine the results of multiple conditions
+  // to determine if an incident should be opened.
+  ConditionCombinerType combiner = 6;
+
+  // Whether or not the policy is enabled. On write, the default interpretation
+  // if unset is that the policy is enabled. On read, clients should not make
+  // any assumption about the state if it has not been populated. The
+  // field should always be populated on List and Get operations, unless
+  // a field projection has been specified that strips it out.
+  google.protobuf.BoolValue enabled = 17;
+
+  // Identifies the notification channels to which notifications should be sent
+  // when incidents are opened or closed or when new violations occur on
+  // an already opened incident. Each element of this array corresponds to
+  // the `name` field in each of the
+  // [`NotificationChannel`][google.monitoring.v3.NotificationChannel]
+  // objects that are returned from the [`ListNotificationChannels`]
+  // [google.monitoring.v3.NotificationChannelService.ListNotificationChannels]
+  // method. The syntax of the entries in this field is:
+  //
+  //     projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]
+  repeated string notification_channels = 14;
+
+  // A read-only record of the creation of the alerting policy. If provided
+  // in a call to create or update, this field will be ignored.
+  MutationRecord creation_record = 10;
+
+  // A read-only record of the most recent change to the alerting policy. If
+  // provided in a call to create or update, this field will be ignored.
+  MutationRecord mutation_record = 11;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/alert_service.proto b/monitoring/google/cloud/monitoring_v3/proto/alert_service.proto
new file mode 100644
index 000000000000..c97e3dc0585f
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/alert_service.proto
@@ -0,0 +1,198 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/annotations.proto";
+import "google/monitoring/v3/alert.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "AlertServiceProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// The AlertPolicyService API is used to manage (list, create, delete,
+// edit) alert policies in Stackdriver Monitoring. An alerting policy is
+// a description of the conditions under which some aspect of your
+// system is considered to be "unhealthy" and the ways to notify
+// people or services about this state. In addition to using this API, alert
+// policies can also be managed through
+// [Stackdriver Monitoring](https://cloud.google.com/monitoring/docs/),
+// which can be reached by clicking the "Monitoring" tab in
+// [Cloud Console](https://console.cloud.google.com/).
+service AlertPolicyService {
+  // Lists the existing alerting policies for the project.
+  rpc ListAlertPolicies(ListAlertPoliciesRequest) returns (ListAlertPoliciesResponse) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*}/alertPolicies"
+    };
+  }
+
+  // Gets a single alerting policy.
+  rpc GetAlertPolicy(GetAlertPolicyRequest) returns (AlertPolicy) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*/alertPolicies/*}"
+    };
+  }
+
+  // Creates a new alerting policy.
+  rpc CreateAlertPolicy(CreateAlertPolicyRequest) returns (AlertPolicy) {
+    option (google.api.http) = {
+      post: "/v3/{name=projects/*}/alertPolicies"
+      body: "alert_policy"
+    };
+  }
+
+  // Deletes an alerting policy.
+  rpc DeleteAlertPolicy(DeleteAlertPolicyRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v3/{name=projects/*/alertPolicies/*}"
+    };
+  }
+
+  // Updates an alerting policy. You can either replace the entire policy with
+  // a new one or replace only certain fields in the current alerting policy by
+  // specifying the fields to be updated via `updateMask`. Returns the
+  // updated alerting policy.
+  rpc UpdateAlertPolicy(UpdateAlertPolicyRequest) returns (AlertPolicy) {
+    option (google.api.http) = {
+      patch: "/v3/{alert_policy.name=projects/*/alertPolicies/*}"
+      body: "alert_policy"
+    };
+  }
+}
+
+// The protocol for the `CreateAlertPolicy` request.
+message CreateAlertPolicyRequest {
+  // The project in which to create the alerting policy. The format is
+  // `projects/[PROJECT_ID]`.
+  //
+  // Note that this field names the parent container in which the alerting
+  // policy will be written, not the name of the created policy. The alerting
+  // policy that is returned will have a name that contains a normalized
+  // representation of this name as a prefix but adds a suffix of the form
+  // `/alertPolicies/[POLICY_ID]`, identifying the policy in the container.
+  string name = 3;
+
+  // The requested alerting policy. You should omit the `name` field in this
+  // policy. The name will be returned in the new policy, including
+  // a new [ALERT_POLICY_ID] value.
+  AlertPolicy alert_policy = 2;
+}
+
+// The protocol for the `GetAlertPolicy` request.
+message GetAlertPolicyRequest {
+  // The alerting policy to retrieve. The format is
+  //
+  //     projects/[PROJECT_ID]/alertPolicies/[ALERT_POLICY_ID]
+  string name = 3;
+}
+
+// The protocol for the `ListAlertPolicies` request.
+message ListAlertPoliciesRequest {
+  // The project whose alert policies are to be listed. The format is
+  //
+  //     projects/[PROJECT_ID]
+  //
+  // Note that this field names the parent container in which the alerting
+  // policies to be listed are stored. To retrieve a single alerting policy
+  // by name, use the
+  // [GetAlertPolicy][google.monitoring.v3.AlertPolicyService.GetAlertPolicy]
+  // operation, instead.
+  string name = 4;
+
+  // If provided, this field specifies the criteria that must be met by
+  // alert policies to be included in the response.
+  //
+  // For more details, see [sorting and
+  // filtering](/monitoring/api/v3/sorting-and-filtering).
+  string filter = 5;
+
+  // A comma-separated list of fields by which to sort the result. Supports
+  // the same set of field references as the `filter` field. Entries can be
+  // prefixed with a minus sign to sort by the field in descending order.
+  //
+  // For more details, see [sorting and
+  // filtering](/monitoring/api/v3/sorting-and-filtering).
+  string order_by = 6;
+
+  // The maximum number of results to return in a single response.
+  int32 page_size = 2;
+
+  // If this field is not empty then it must contain the `nextPageToken` value
+  // returned by a previous call to this method.  Using this field causes the
+  // method to return more results from the previous method call.
+  string page_token = 3;
+}
+
+// The protocol for the `ListAlertPolicies` response.
+message ListAlertPoliciesResponse {
+  // The returned alert policies.
+  repeated AlertPolicy alert_policies = 3;
+
+  // If there might be more results than were returned, then this field is set
+  // to a non-empty value. To see the additional results,
+  // use that value as `pageToken` in the next call to this method.
+  string next_page_token = 2;
+}
+
+// The protocol for the `UpdateAlertPolicy` request.
+message UpdateAlertPolicyRequest {
+  // Optional. A list of alerting policy field names. If this field is not
+  // empty, each listed field in the existing alerting policy is set to the
+  // value of the corresponding field in the supplied policy (`alert_policy`),
+  // or to the field's default value if the field is not in the supplied
+  // alerting policy.  Fields not listed retain their previous value.
+  //
+  // Examples of valid field masks include `display_name`, `documentation`,
+  // `documentation.content`, `documentation.mime_type`, `user_labels`,
+  // `user_label.nameofkey`, `enabled`, `conditions`, `combiner`, etc.
+  //
+  // If this field is empty, then the supplied alerting policy replaces the
+  // existing policy. It is the same as deleting the existing policy and
+  // adding the supplied policy, except for the following:
+  //
+  // +   The new policy will have the same `[ALERT_POLICY_ID]` as the former
+  //     policy. This gives you continuity with the former policy in your
+  //     notifications and incidents.
+  // +   Conditions in the new policy will keep their former `[CONDITION_ID]` if
+  //     the supplied condition includes the `name` field with that
+  //     `[CONDITION_ID]`. If the supplied condition omits the `name` field,
+  //     then a new `[CONDITION_ID]` is created.
+  google.protobuf.FieldMask update_mask = 2;
+
+  // Required. The updated alerting policy or the updated values for the
+  // fields listed in `update_mask`.
+  // If `update_mask` is not empty, any fields in this policy that are
+  // not in `update_mask` are ignored.
+  AlertPolicy alert_policy = 3;
+}
+
+// The protocol for the `DeleteAlertPolicy` request.
+message DeleteAlertPolicyRequest {
+  // The alerting policy to delete. The format is:
+  //
+  //     projects/[PROJECT_ID]/alertPolicies/[ALERT_POLICY_ID]
+  //
+  // For more information, see [AlertPolicy][google.monitoring.v3.AlertPolicy].
+  string name = 3;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/common.proto b/monitoring/google/cloud/monitoring_v3/proto/common.proto
new file mode 100644
index 000000000000..f33af523bd2c
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/common.proto
@@ -0,0 +1,416 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/annotations.proto";
+import "google/api/distribution.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "CommonProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// A single strongly-typed value.
+message TypedValue {
+  // The typed value field.
+  oneof value {
+    // A Boolean value: `true` or `false`.
+    bool bool_value = 1;
+
+    // A 64-bit integer. Its range is approximately &plusmn;9.2x10<sup>18</sup>.
+    int64 int64_value = 2;
+
+    // A 64-bit double-precision floating-point number. Its magnitude
+    // is approximately &plusmn;10<sup>&plusmn;300</sup> and it has 16
+    // significant digits of precision.
+    double double_value = 3;
+
+    // A variable-length string value.
+    string string_value = 4;
+
+    // A distribution value.
+    google.api.Distribution distribution_value = 5;
+  }
+}
+
+// A time interval extending just after a start time through an end time.
+// If the start time is the same as the end time, then the interval
+// represents a single point in time.
+message TimeInterval {
+  // Required. The end of the time interval.
+  google.protobuf.Timestamp end_time = 2;
+
+  // Optional. The beginning of the time interval.  The default value
+  // for the start time is the end time. The start time must not be
+  // later than the end time.
+  google.protobuf.Timestamp start_time = 1;
+}
+
+// Describes how to combine multiple time series to provide different views of
+// the data.  Aggregation consists of an alignment step on individual time
+// series (`alignment_period` and `per_series_aligner`) followed by an optional
+// reduction step of the data across the aligned time series
+// (`cross_series_reducer` and `group_by_fields`).  For more details, see
+// [Aggregation](/monitoring/api/learn_more#aggregation).
+message Aggregation {
+  // The Aligner describes how to bring the data points in a single
+  // time series into temporal alignment.
+  enum Aligner {
+    // No alignment. Raw data is returned. Not valid if cross-time
+    // series reduction is requested. The value type of the result is
+    // the same as the value type of the input.
+    ALIGN_NONE = 0;
+
+    // Align and convert to delta metric type. This alignment is valid
+    // for cumulative metrics and delta metrics. Aligning an existing
+    // delta metric to a delta metric requires that the alignment
+    // period be increased. The value type of the result is the same
+    // as the value type of the input.
+    //
+    // One can think of this aligner as a rate but without time units; that
+    // is, the output is conceptually (second_point - first_point).
+    ALIGN_DELTA = 1;
+
+    // Align and convert to a rate. This alignment is valid for
+    // cumulative metrics and delta metrics with numeric values. The output is a
+    // gauge metric with value type
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    //
+    // One can think of this aligner as conceptually providing the slope of
+    // the line that passes through the value at the start and end of the
+    // window. In other words, this is conceptually ((y1 - y0)/(t1 - t0)),
+    // and the output unit is one that has a "/time" dimension.
+    //
+    // If, by rate, you are looking for percentage change, see the
+    // `ALIGN_PERCENT_CHANGE` aligner option.
+    ALIGN_RATE = 2;
+
+    // Align by interpolating between adjacent points around the
+    // period boundary. This alignment is valid for gauge
+    // metrics with numeric values. The value type of the result is the same
+    // as the value type of the input.
+    ALIGN_INTERPOLATE = 3;
+
+    // Align by shifting the oldest data point before the period
+    // boundary to the boundary. This alignment is valid for gauge
+    // metrics. The value type of the result is the same as the
+    // value type of the input.
+    ALIGN_NEXT_OLDER = 4;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the minimum of all data points in the
+    // period. This alignment is valid for gauge and delta metrics with numeric
+    // values. The value type of the result is the same as the value
+    // type of the input.
+    ALIGN_MIN = 10;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the maximum of all data points in the
+    // period. This alignment is valid for gauge and delta metrics with numeric
+    // values. The value type of the result is the same as the value
+    // type of the input.
+    ALIGN_MAX = 11;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the average or arithmetic mean of all
+    // data points in the period. This alignment is valid for gauge and delta
+    // metrics with numeric values. The value type of the output is
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    ALIGN_MEAN = 12;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the count of all data points in the
+    // period. This alignment is valid for gauge and delta metrics with numeric
+    // or Boolean values. The value type of the output is
+    // [INT64][google.api.MetricDescriptor.ValueType.INT64].
+    ALIGN_COUNT = 13;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the sum of all data points in the
+    // period. This alignment is valid for gauge and delta metrics with numeric
+    // and distribution values. The value type of the output is the
+    // same as the value type of the input.
+    ALIGN_SUM = 14;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the standard deviation of all data
+    // points in the period. This alignment is valid for gauge and delta metrics
+    // with numeric values. The value type of the output is
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    ALIGN_STDDEV = 15;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the count of True-valued data points in the
+    // period. This alignment is valid for gauge metrics with
+    // Boolean values. The value type of the output is
+    // [INT64][google.api.MetricDescriptor.ValueType.INT64].
+    ALIGN_COUNT_TRUE = 16;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the count of False-valued data points in the
+    // period. This alignment is valid for gauge metrics with
+    // Boolean values. The value type of the output is
+    // [INT64][google.api.MetricDescriptor.ValueType.INT64].
+    ALIGN_COUNT_FALSE = 24;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the fraction of True-valued data points in the
+    // period. This alignment is valid for gauge metrics with Boolean values.
+    // The output value is in the range [0, 1] and has value type
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    ALIGN_FRACTION_TRUE = 17;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the 99th percentile of all data
+    // points in the period. This alignment is valid for gauge and delta metrics
+    // with distribution values. The output is a gauge metric with value type
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    ALIGN_PERCENTILE_99 = 18;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the 95th percentile of all data
+    // points in the period. This alignment is valid for gauge and delta metrics
+    // with distribution values. The output is a gauge metric with value type
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    ALIGN_PERCENTILE_95 = 19;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the 50th percentile of all data
+    // points in the period. This alignment is valid for gauge and delta metrics
+    // with distribution values. The output is a gauge metric with value type
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    ALIGN_PERCENTILE_50 = 20;
+
+    // Align time series via aggregation. The resulting data point in
+    // the alignment period is the 5th percentile of all data
+    // points in the period. This alignment is valid for gauge and delta metrics
+    // with distribution values. The output is a gauge metric with value type
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    ALIGN_PERCENTILE_05 = 21;
+
+    // Align and convert to a percentage change. This alignment is valid for
+    // gauge and delta metrics with numeric values. This alignment conceptually
+    // computes the equivalent of "((current - previous)/previous)*100"
+    // where previous value is determined based on the alignmentPeriod.
+    // In the event that previous is 0 the calculated value is infinity with the
+    // exception that if both (current - previous) and previous are 0 the
+    // calculated value is 0.
+    // A 10 minute moving mean is computed at each point of the time window
+    // prior to the above calculation to smooth the metric and prevent false
+    // positives from very short lived spikes.
+    // Only applicable for data that is >= 0. Any values < 0 are treated as
+    // no data. While delta metrics are accepted by this alignment special care
+    // should be taken that the values for the metric will always be positive.
+    // The output is a gauge metric with value type
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    ALIGN_PERCENT_CHANGE = 23;
+  }
+
+  // A Reducer describes how to aggregate data points from multiple
+  // time series into a single time series.
+  enum Reducer {
+    // No cross-time series reduction. The output of the aligner is
+    // returned.
+    REDUCE_NONE = 0;
+
+    // Reduce by computing the mean across time series for each
+    // alignment period. This reducer is valid for delta and
+    // gauge metrics with numeric or distribution values. The value type of the
+    // output is [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    REDUCE_MEAN = 1;
+
+    // Reduce by computing the minimum across time series for each
+    // alignment period. This reducer is valid for delta and
+    // gauge metrics with numeric values. The value type of the output
+    // is the same as the value type of the input.
+    REDUCE_MIN = 2;
+
+    // Reduce by computing the maximum across time series for each
+    // alignment period. This reducer is valid for delta and
+    // gauge metrics with numeric values. The value type of the output
+    // is the same as the value type of the input.
+    REDUCE_MAX = 3;
+
+    // Reduce by computing the sum across time series for each
+    // alignment period. This reducer is valid for delta and
+    // gauge metrics with numeric and distribution values. The value type of
+    // the output is the same as the value type of the input.
+    REDUCE_SUM = 4;
+
+    // Reduce by computing the standard deviation across time series
+    // for each alignment period. This reducer is valid for delta
+    // and gauge metrics with numeric or distribution values. The value type of
+    // the output is [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    REDUCE_STDDEV = 5;
+
+    // Reduce by computing the count of data points across time series
+    // for each alignment period. This reducer is valid for delta
+    // and gauge metrics of numeric, Boolean, distribution, and string value
+    // type. The value type of the output is
+    // [INT64][google.api.MetricDescriptor.ValueType.INT64].
+    REDUCE_COUNT = 6;
+
+    // Reduce by computing the count of True-valued data points across time
+    // series for each alignment period. This reducer is valid for delta
+    // and gauge metrics of Boolean value type. The value type of
+    // the output is [INT64][google.api.MetricDescriptor.ValueType.INT64].
+    REDUCE_COUNT_TRUE = 7;
+
+    // Reduce by computing the count of False-valued data points across time
+    // series for each alignment period. This reducer is valid for delta
+    // and gauge metrics of Boolean value type. The value type of
+    // the output is [INT64][google.api.MetricDescriptor.ValueType.INT64].
+    REDUCE_COUNT_FALSE = 15;
+
+    // Reduce by computing the fraction of True-valued data points across time
+    // series for each alignment period. This reducer is valid for delta
+    // and gauge metrics of Boolean value type. The output value is in the
+    // range [0, 1] and has value type
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
+    REDUCE_FRACTION_TRUE = 8;
+
+    // Reduce by computing 99th percentile of data points across time series
+    // for each alignment period. This reducer is valid for gauge and delta
+    // metrics of numeric and distribution type. The value of the output is
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
+    REDUCE_PERCENTILE_99 = 9;
+
+    // Reduce by computing 95th percentile of data points across time series
+    // for each alignment period. This reducer is valid for gauge and delta
+    // metrics of numeric and distribution type. The value of the output is
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
+    REDUCE_PERCENTILE_95 = 10;
+
+    // Reduce by computing 50th percentile of data points across time series
+    // for each alignment period. This reducer is valid for gauge and delta
+    // metrics of numeric and distribution type. The value of the output is
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
+    REDUCE_PERCENTILE_50 = 11;
+
+    // Reduce by computing 5th percentile of data points across time series
+    // for each alignment period. This reducer is valid for gauge and delta
+    // metrics of numeric and distribution type. The value of the output is
+    // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
+    REDUCE_PERCENTILE_05 = 12;
+  }
+
+  // The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
+  // alignment. If present, `alignmentPeriod` must be at least 60
+  // seconds.  After per-time series alignment, each time series will
+  // contain data points only on the period boundaries. If
+  // `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
+  // this field is ignored. If `perSeriesAligner` is specified and
+  // does not equal `ALIGN_NONE`, then this field must be defined;
+  // otherwise an error is returned.
+  google.protobuf.Duration alignment_period = 1;
+
+  // The approach to be used to align individual time series. Not all
+  // alignment functions may be applied to all time series, depending
+  // on the metric type and value type of the original time
+  // series. Alignment may change the metric type or the value type of
+  // the time series.
+  //
+  // Time series data must be aligned in order to perform cross-time
+  // series reduction. If `crossSeriesReducer` is specified, then
+  // `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
+  // and `alignmentPeriod` must be specified; otherwise, an error is
+  // returned.
+  Aligner per_series_aligner = 2;
+
+  // The approach to be used to combine time series. Not all reducer
+  // functions may be applied to all time series, depending on the
+  // metric type and the value type of the original time
+  // series. Reduction may change the metric type of value type of the
+  // time series.
+  //
+  // Time series data must be aligned in order to perform cross-time
+  // series reduction. If `crossSeriesReducer` is specified, then
+  // `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
+  // and `alignmentPeriod` must be specified; otherwise, an error is
+  // returned.
+  Reducer cross_series_reducer = 4;
+
+  // The set of fields to preserve when `crossSeriesReducer` is
+  // specified. The `groupByFields` determine how the time series are
+  // partitioned into subsets prior to applying the aggregation
+  // function. Each subset contains time series that have the same
+  // value for each of the grouping fields. Each individual time
+  // series is a member of exactly one subset. The
+  // `crossSeriesReducer` is applied to each subset of time series.
+  // It is not possible to reduce across different resource types, so
+  // this field implicitly contains `resource.type`.  Fields not
+  // specified in `groupByFields` are aggregated away.  If
+  // `groupByFields` is not specified and all the time series have
+  // the same resource type, then the time series are aggregated into
+  // a single output time series. If `crossSeriesReducer` is not
+  // defined, this field is ignored.
+  repeated string group_by_fields = 5;
+}
+
+// Specifies an ordering relationship on two arguments, here called left and
+// right.
+enum ComparisonType {
+  // No ordering relationship is specified.
+  COMPARISON_UNSPECIFIED = 0;
+
+  // The left argument is greater than the right argument.
+  COMPARISON_GT = 1;
+
+  // The left argument is greater than or equal to the right argument.
+  COMPARISON_GE = 2;
+
+  // The left argument is less than the right argument.
+  COMPARISON_LT = 3;
+
+  // The left argument is less than or equal to the right argument.
+  COMPARISON_LE = 4;
+
+  // The left argument is equal to the right argument.
+  COMPARISON_EQ = 5;
+
+  // The left argument is not equal to the right argument.
+  COMPARISON_NE = 6;
+}
+
+// The tier of service for a Workspace. Please see the
+// [service tiers documentation](https://cloud.google.com/monitoring/workspaces/tiers)
+// for more details.
+enum ServiceTier {
+  option deprecated = true;
+
+  // An invalid sentinel value, used to indicate that a tier has not
+  // been provided explicitly.
+  SERVICE_TIER_UNSPECIFIED = 0;
+
+  // The Stackdriver Basic tier, a free tier of service that provides basic
+  // features, a moderate allotment of logs, and access to built-in metrics.
+  // A number of features are not available in this tier. For more details,
+  // see [the service tiers documentation](https://cloud.google.com/monitoring/workspaces/tiers).
+  SERVICE_TIER_BASIC = 1;
+
+  // The Stackdriver Premium tier, a higher, more expensive tier of service
+  // that provides access to all Stackdriver features, lets you use Stackdriver
+  // with AWS accounts, and has a larger allotments for logs and metrics. For
+  // more details, see [the service tiers documentation](https://cloud.google.com/monitoring/workspaces/tiers).
+  SERVICE_TIER_PREMIUM = 2;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/common_pb2.py b/monitoring/google/cloud/monitoring_v3/proto/common_pb2.py
index f4d3a879952e..a14be15ccf04 100644
--- a/monitoring/google/cloud/monitoring_v3/proto/common_pb2.py
+++ b/monitoring/google/cloud/monitoring_v3/proto/common_pb2.py
@@ -771,3 +771,4 @@
 DESCRIPTOR._options = None
 _SERVICETIER._options = None
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/monitoring/google/cloud/monitoring_v3/proto/dropped_labels.proto b/monitoring/google/cloud/monitoring_v3/proto/dropped_labels.proto
new file mode 100644
index 000000000000..11287062e811
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/dropped_labels.proto
@@ -0,0 +1,43 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+
+
+// A set of (label, value) pairs which were dropped during aggregation, attached
+// to google.api.Distribution.Exemplars in google.api.Distribution values during
+// aggregation.
+//
+// These values are used in combination with the label values that remain on the
+// aggregated Distribution timeseries to construct the full label set for the
+// exemplar values.  The resulting full label set may be used to identify the
+// specific task/job/instance (for example) which may be contributing to a
+// long-tail, while allowing the storage savings of only storing aggregated
+// distribution values for a large group.
+//
+// Note that there are no guarantees on ordering of the labels from
+// exemplar-to-exemplar and from distribution-to-distribution in the same
+// stream, and there may be duplicates.  It is up to clients to resolve any
+// ambiguities.
+message DroppedLabels {
+  // Map from label to its value, for all labels dropped in any aggregation.
+  map<string, string> label = 1;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/group.proto b/monitoring/google/cloud/monitoring_v3/proto/group.proto
new file mode 100644
index 000000000000..f7f49615bd74
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/group.proto
@@ -0,0 +1,76 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "GroupProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// The description of a dynamic collection of monitored resources. Each group
+// has a filter that is matched against monitored resources and their associated
+// metadata. If a group's filter matches an available monitored resource, then
+// that resource is a member of that group.  Groups can contain any number of
+// monitored resources, and each monitored resource can be a member of any
+// number of groups.
+//
+// Groups can be nested in parent-child hierarchies. The `parentName` field
+// identifies an optional parent for each group.  If a group has a parent, then
+// the only monitored resources available to be matched by the group's filter
+// are the resources contained in the parent group.  In other words, a group
+// contains the monitored resources that match its filter and the filters of all
+// the group's ancestors.  A group without a parent can contain any monitored
+// resource.
+//
+// For example, consider an infrastructure running a set of instances with two
+// user-defined tags: `"environment"` and `"role"`. A parent group has a filter,
+// `environment="production"`.  A child of that parent group has a filter,
+// `role="transcoder"`.  The parent group contains all instances in the
+// production environment, regardless of their roles.  The child group contains
+// instances that have the transcoder role *and* are in the production
+// environment.
+//
+// The monitored resources contained in a group can change at any moment,
+// depending on what resources exist and what filters are associated with the
+// group and its ancestors.
+message Group {
+  // Output only. The name of this group. The format is
+  // `"projects/{project_id_or_number}/groups/{group_id}"`.
+  // When creating a group, this field is ignored and a new name is created
+  // consisting of the project specified in the call to `CreateGroup`
+  // and a unique `{group_id}` that is generated automatically.
+  string name = 1;
+
+  // A user-assigned name for this group, used only for display purposes.
+  string display_name = 2;
+
+  // The name of the group's parent, if it has one.
+  // The format is `"projects/{project_id_or_number}/groups/{group_id}"`.
+  // For groups with no parent, `parentName` is the empty string, `""`.
+  string parent_name = 3;
+
+  // The filter used to determine which monitored resources belong to this group.
+  string filter = 5;
+
+  // If true, the members of this group are considered to be a cluster.
+  // The system can perform additional analysis on groups that are clusters.
+  bool is_cluster = 6;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/group_service.proto b/monitoring/google/cloud/monitoring_v3/proto/group_service.proto
new file mode 100644
index 000000000000..4af7e3719a10
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/group_service.proto
@@ -0,0 +1,222 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/annotations.proto";
+import "google/api/monitored_resource.proto";
+import "google/monitoring/v3/common.proto";
+import "google/monitoring/v3/group.proto";
+import "google/protobuf/empty.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "GroupServiceProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// The Group API lets you inspect and manage your
+// [groups](#google.monitoring.v3.Group).
+//
+// A group is a named filter that is used to identify
+// a collection of monitored resources. Groups are typically used to
+// mirror the physical and/or logical topology of the environment.
+// Because group membership is computed dynamically, monitored
+// resources that are started in the future are automatically placed
+// in matching groups. By using a group to name monitored resources in,
+// for example, an alert policy, the target of that alert policy is
+// updated automatically as monitored resources are added and removed
+// from the infrastructure.
+service GroupService {
+  // Lists the existing groups.
+  rpc ListGroups(ListGroupsRequest) returns (ListGroupsResponse) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*}/groups"
+    };
+  }
+
+  // Gets a single group.
+  rpc GetGroup(GetGroupRequest) returns (Group) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*/groups/*}"
+    };
+  }
+
+  // Creates a new group.
+  rpc CreateGroup(CreateGroupRequest) returns (Group) {
+    option (google.api.http) = {
+      post: "/v3/{name=projects/*}/groups"
+      body: "group"
+    };
+  }
+
+  // Updates an existing group.
+  // You can change any group attributes except `name`.
+  rpc UpdateGroup(UpdateGroupRequest) returns (Group) {
+    option (google.api.http) = {
+      put: "/v3/{group.name=projects/*/groups/*}"
+      body: "group"
+    };
+  }
+
+  // Deletes an existing group.
+  rpc DeleteGroup(DeleteGroupRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v3/{name=projects/*/groups/*}"
+    };
+  }
+
+  // Lists the monitored resources that are members of a group.
+  rpc ListGroupMembers(ListGroupMembersRequest) returns (ListGroupMembersResponse) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*/groups/*}/members"
+    };
+  }
+}
+
+// The `ListGroup` request.
+message ListGroupsRequest {
+  // The project whose groups are to be listed. The format is
+  // `"projects/{project_id_or_number}"`.
+  string name = 7;
+
+  // An optional filter consisting of a single group name.  The filters limit the
+  // groups returned based on their parent-child relationship with the specified
+  // group. If no filter is specified, all groups are returned.
+  oneof filter {
+    // A group name: `"projects/{project_id_or_number}/groups/{group_id}"`.
+    // Returns groups whose `parentName` field contains the group
+    // name.  If no groups have this parent, the results are empty.
+    string children_of_group = 2;
+
+    // A group name: `"projects/{project_id_or_number}/groups/{group_id}"`.
+    // Returns groups that are ancestors of the specified group.
+    // The groups are returned in order, starting with the immediate parent and
+    // ending with the most distant ancestor.  If the specified group has no
+    // immediate parent, the results are empty.
+    string ancestors_of_group = 3;
+
+    // A group name: `"projects/{project_id_or_number}/groups/{group_id}"`.
+    // Returns the descendants of the specified group.  This is a superset of
+    // the results returned by the `childrenOfGroup` filter, and includes
+    // children-of-children, and so forth.
+    string descendants_of_group = 4;
+  }
+
+  // A positive number that is the maximum number of results to return.
+  int32 page_size = 5;
+
+  // If this field is not empty then it must contain the `nextPageToken` value
+  // returned by a previous call to this method.  Using this field causes the
+  // method to return additional results from the previous method call.
+  string page_token = 6;
+}
+
+// The `ListGroups` response.
+message ListGroupsResponse {
+  // The groups that match the specified filters.
+  repeated Group group = 1;
+
+  // If there are more results than have been returned, then this field is set
+  // to a non-empty value.  To see the additional results,
+  // use that value as `pageToken` in the next call to this method.
+  string next_page_token = 2;
+}
+
+// The `GetGroup` request.
+message GetGroupRequest {
+  // The group to retrieve. The format is
+  // `"projects/{project_id_or_number}/groups/{group_id}"`.
+  string name = 3;
+}
+
+// The `CreateGroup` request.
+message CreateGroupRequest {
+  // The project in which to create the group. The format is
+  // `"projects/{project_id_or_number}"`.
+  string name = 4;
+
+  // A group definition. It is an error to define the `name` field because
+  // the system assigns the name.
+  Group group = 2;
+
+  // If true, validate this request but do not create the group.
+  bool validate_only = 3;
+}
+
+// The `UpdateGroup` request.
+message UpdateGroupRequest {
+  // The new definition of the group.  All fields of the existing group,
+  // excepting `name`, are replaced with the corresponding fields of this group.
+  Group group = 2;
+
+  // If true, validate this request but do not update the existing group.
+  bool validate_only = 3;
+}
+
+// The `DeleteGroup` request. You can only delete a group if it has no children.
+message DeleteGroupRequest {
+  // The group to delete. The format is
+  // `"projects/{project_id_or_number}/groups/{group_id}"`.
+  string name = 3;
+}
+
+// The `ListGroupMembers` request.
+message ListGroupMembersRequest {
+  // The group whose members are listed. The format is
+  // `"projects/{project_id_or_number}/groups/{group_id}"`.
+  string name = 7;
+
+  // A positive number that is the maximum number of results to return.
+  int32 page_size = 3;
+
+  // If this field is not empty then it must contain the `nextPageToken` value
+  // returned by a previous call to this method.  Using this field causes the
+  // method to return additional results from the previous method call.
+  string page_token = 4;
+
+  // An optional [list filter](/monitoring/api/learn_more#filtering) describing
+  // the members to be returned.  The filter may reference the type, labels, and
+  // metadata of monitored resources that comprise the group.
+  // For example, to return only resources representing Compute Engine VM
+  // instances, use this filter:
+  //
+  //     resource.type = "gce_instance"
+  string filter = 5;
+
+  // An optional time interval for which results should be returned. Only
+  // members that were part of the group during the specified interval are
+  // included in the response.  If no interval is provided then the group
+  // membership over the last minute is returned.
+  TimeInterval interval = 6;
+}
+
+// The `ListGroupMembers` response.
+message ListGroupMembersResponse {
+  // A set of monitored resources in the group.
+  repeated google.api.MonitoredResource members = 1;
+
+  // If there are more results than have been returned, then this field is
+  // set to a non-empty value.  To see the additional results, use that value as
+  // `pageToken` in the next call to this method.
+  string next_page_token = 2;
+
+  // The total number of elements matching this request.
+  int32 total_size = 3;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/metric.proto b/monitoring/google/cloud/monitoring_v3/proto/metric.proto
new file mode 100644
index 000000000000..570313229cc9
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/metric.proto
@@ -0,0 +1,96 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/annotations.proto";
+import "google/api/label.proto";
+import "google/api/metric.proto";
+import "google/api/monitored_resource.proto";
+import "google/monitoring/v3/common.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "MetricProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// A single data point in a time series.
+message Point {
+  // The time interval to which the data point applies.  For `GAUGE` metrics,
+  // only the end time of the interval is used.  For `DELTA` metrics, the start
+  // and end time should specify a non-zero interval, with subsequent points
+  // specifying contiguous and non-overlapping intervals.  For `CUMULATIVE`
+  // metrics, the start and end time should specify a non-zero interval, with
+  // subsequent points specifying the same start time and increasing end times,
+  // until an event resets the cumulative value to zero and sets a new start
+  // time for the following points.
+  TimeInterval interval = 1;
+
+  // The value of the data point.
+  TypedValue value = 2;
+}
+
+// A collection of data points that describes the time-varying values
+// of a metric. A time series is identified by a combination of a
+// fully-specified monitored resource and a fully-specified metric.
+// This type is used for both listing and creating time series.
+message TimeSeries {
+  // The associated metric. A fully-specified metric used to identify the time
+  // series.
+  google.api.Metric metric = 1;
+
+  // The associated monitored resource.  Custom metrics can use only certain
+  // monitored resource types in their time series data.
+  google.api.MonitoredResource resource = 2;
+
+  // Output only. The associated monitored resource metadata. When reading a
+  // a timeseries, this field will include metadata labels that are explicitly
+  // named in the reduction. When creating a timeseries, this field is ignored.
+  google.api.MonitoredResourceMetadata metadata = 7;
+
+  // The metric kind of the time series. When listing time series, this metric
+  // kind might be different from the metric kind of the associated metric if
+  // this time series is an alignment or reduction of other time series.
+  //
+  // When creating a time series, this field is optional. If present, it must be
+  // the same as the metric kind of the associated metric. If the associated
+  // metric's descriptor must be auto-created, then this field specifies the
+  // metric kind of the new descriptor and must be either `GAUGE` (the default)
+  // or `CUMULATIVE`.
+  google.api.MetricDescriptor.MetricKind metric_kind = 3;
+
+  // The value type of the time series. When listing time series, this value
+  // type might be different from the value type of the associated metric if
+  // this time series is an alignment or reduction of other time series.
+  //
+  // When creating a time series, this field is optional. If present, it must be
+  // the same as the type of the data in the `points` field.
+  google.api.MetricDescriptor.ValueType value_type = 4;
+
+  // The data points of this time series. When listing time series, points are
+  // returned in reverse time order.
+  //
+  // When creating a time series, this field must contain exactly one point and
+  // the point's type must be the same as the value type of the associated
+  // metric. If the associated metric's descriptor must be auto-created, then
+  // the value type of the descriptor is determined by the point's type, which
+  // must be `BOOL`, `INT64`, `DOUBLE`, or `DISTRIBUTION`.
+  repeated Point points = 5;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/metric_service.proto b/monitoring/google/cloud/monitoring_v3/proto/metric_service.proto
new file mode 100644
index 000000000000..faf758e14a38
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/metric_service.proto
@@ -0,0 +1,311 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/annotations.proto";
+import "google/api/metric.proto";
+import "google/api/monitored_resource.proto";
+import "google/monitoring/v3/common.proto";
+import "google/monitoring/v3/metric.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "MetricServiceProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// Manages metric descriptors, monitored resource descriptors, and
+// time series data.
+service MetricService {
+  // Lists monitored resource descriptors that match a filter. This method does not require a Stackdriver account.
+  rpc ListMonitoredResourceDescriptors(ListMonitoredResourceDescriptorsRequest) returns (ListMonitoredResourceDescriptorsResponse) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*}/monitoredResourceDescriptors"
+    };
+  }
+
+  // Gets a single monitored resource descriptor. This method does not require a Stackdriver account.
+  rpc GetMonitoredResourceDescriptor(GetMonitoredResourceDescriptorRequest) returns (google.api.MonitoredResourceDescriptor) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*/monitoredResourceDescriptors/*}"
+    };
+  }
+
+  // Lists metric descriptors that match a filter. This method does not require a Stackdriver account.
+  rpc ListMetricDescriptors(ListMetricDescriptorsRequest) returns (ListMetricDescriptorsResponse) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*}/metricDescriptors"
+    };
+  }
+
+  // Gets a single metric descriptor. This method does not require a Stackdriver account.
+  rpc GetMetricDescriptor(GetMetricDescriptorRequest) returns (google.api.MetricDescriptor) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*/metricDescriptors/**}"
+    };
+  }
+
+  // Creates a new metric descriptor.
+  // User-created metric descriptors define
+  // [custom metrics](/monitoring/custom-metrics).
+  rpc CreateMetricDescriptor(CreateMetricDescriptorRequest) returns (google.api.MetricDescriptor) {
+    option (google.api.http) = {
+      post: "/v3/{name=projects/*}/metricDescriptors"
+      body: "metric_descriptor"
+    };
+  }
+
+  // Deletes a metric descriptor. Only user-created
+  // [custom metrics](/monitoring/custom-metrics) can be deleted.
+  rpc DeleteMetricDescriptor(DeleteMetricDescriptorRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v3/{name=projects/*/metricDescriptors/**}"
+    };
+  }
+
+  // Lists time series that match a filter. This method does not require a Stackdriver account.
+  rpc ListTimeSeries(ListTimeSeriesRequest) returns (ListTimeSeriesResponse) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*}/timeSeries"
+    };
+  }
+
+  // Creates or adds data to one or more time series.
+  // The response is empty if all time series in the request were written.
+  // If any time series could not be written, a corresponding failure message is
+  // included in the error response.
+  rpc CreateTimeSeries(CreateTimeSeriesRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v3/{name=projects/*}/timeSeries"
+      body: "*"
+    };
+  }
+}
+
+// The `ListMonitoredResourceDescriptors` request.
+message ListMonitoredResourceDescriptorsRequest {
+  // The project on which to execute the request. The format is
+  // `"projects/{project_id_or_number}"`.
+  string name = 5;
+
+  // An optional [filter](/monitoring/api/v3/filters) describing
+  // the descriptors to be returned.  The filter can reference
+  // the descriptor's type and labels. For example, the
+  // following filter returns only Google Compute Engine descriptors
+  // that have an `id` label:
+  //
+  //     resource.type = starts_with("gce_") AND resource.label:id
+  string filter = 2;
+
+  // A positive number that is the maximum number of results to return.
+  int32 page_size = 3;
+
+  // If this field is not empty then it must contain the `nextPageToken` value
+  // returned by a previous call to this method.  Using this field causes the
+  // method to return additional results from the previous method call.
+  string page_token = 4;
+}
+
+// The `ListMonitoredResourceDescriptors` response.
+message ListMonitoredResourceDescriptorsResponse {
+  // The monitored resource descriptors that are available to this project
+  // and that match `filter`, if present.
+  repeated google.api.MonitoredResourceDescriptor resource_descriptors = 1;
+
+  // If there are more results than have been returned, then this field is set
+  // to a non-empty value.  To see the additional results,
+  // use that value as `pageToken` in the next call to this method.
+  string next_page_token = 2;
+}
+
+// The `GetMonitoredResourceDescriptor` request.
+message GetMonitoredResourceDescriptorRequest {
+  // The monitored resource descriptor to get.  The format is
+  // `"projects/{project_id_or_number}/monitoredResourceDescriptors/{resource_type}"`.
+  // The `{resource_type}` is a predefined type, such as
+  // `cloudsql_database`.
+  string name = 3;
+}
+
+// The `ListMetricDescriptors` request.
+message ListMetricDescriptorsRequest {
+  // The project on which to execute the request. The format is
+  // `"projects/{project_id_or_number}"`.
+  string name = 5;
+
+  // If this field is empty, all custom and
+  // system-defined metric descriptors are returned.
+  // Otherwise, the [filter](/monitoring/api/v3/filters)
+  // specifies which metric descriptors are to be
+  // returned. For example, the following filter matches all
+  // [custom metrics](/monitoring/custom-metrics):
+  //
+  //     metric.type = starts_with("custom.googleapis.com/")
+  string filter = 2;
+
+  // A positive number that is the maximum number of results to return.
+  int32 page_size = 3;
+
+  // If this field is not empty then it must contain the `nextPageToken` value
+  // returned by a previous call to this method.  Using this field causes the
+  // method to return additional results from the previous method call.
+  string page_token = 4;
+}
+
+// The `ListMetricDescriptors` response.
+message ListMetricDescriptorsResponse {
+  // The metric descriptors that are available to the project
+  // and that match the value of `filter`, if present.
+  repeated google.api.MetricDescriptor metric_descriptors = 1;
+
+  // If there are more results than have been returned, then this field is set
+  // to a non-empty value.  To see the additional results,
+  // use that value as `pageToken` in the next call to this method.
+  string next_page_token = 2;
+}
+
+// The `GetMetricDescriptor` request.
+message GetMetricDescriptorRequest {
+  // The metric descriptor on which to execute the request. The format is
+  // `"projects/{project_id_or_number}/metricDescriptors/{metric_id}"`.
+  // An example value of `{metric_id}` is
+  // `"compute.googleapis.com/instance/disk/read_bytes_count"`.
+  string name = 3;
+}
+
+// The `CreateMetricDescriptor` request.
+message CreateMetricDescriptorRequest {
+  // The project on which to execute the request. The format is
+  // `"projects/{project_id_or_number}"`.
+  string name = 3;
+
+  // The new [custom metric](/monitoring/custom-metrics)
+  // descriptor.
+  google.api.MetricDescriptor metric_descriptor = 2;
+}
+
+// The `DeleteMetricDescriptor` request.
+message DeleteMetricDescriptorRequest {
+  // The metric descriptor on which to execute the request. The format is
+  // `"projects/{project_id_or_number}/metricDescriptors/{metric_id}"`.
+  // An example of `{metric_id}` is:
+  // `"custom.googleapis.com/my_test_metric"`.
+  string name = 3;
+}
+
+// The `ListTimeSeries` request.
+message ListTimeSeriesRequest {
+  // Controls which fields are returned by `ListTimeSeries`.
+  enum TimeSeriesView {
+    // Returns the identity of the metric(s), the time series,
+    // and the time series data.
+    FULL = 0;
+
+    // Returns the identity of the metric and the time series resource,
+    // but not the time series data.
+    HEADERS = 1;
+  }
+
+  // The project on which to execute the request. The format is
+  // "projects/{project_id_or_number}".
+  string name = 10;
+
+  // A [monitoring filter](/monitoring/api/v3/filters) that specifies which time
+  // series should be returned.  The filter must specify a single metric type,
+  // and can additionally specify metric labels and other information. For
+  // example:
+  //
+  //     metric.type = "compute.googleapis.com/instance/cpu/usage_time" AND
+  //         metric.label.instance_name = "my-instance-name"
+  string filter = 2;
+
+  // The time interval for which results should be returned. Only time series
+  // that contain data points in the specified interval are included
+  // in the response.
+  TimeInterval interval = 4;
+
+  // By default, the raw time series data is returned.
+  // Use this field to combine multiple time series for different
+  // views of the data.
+  Aggregation aggregation = 5;
+
+  // Unsupported: must be left blank. The points in each time series are
+  // returned in reverse time order.
+  string order_by = 6;
+
+  // Specifies which information is returned about the time series.
+  TimeSeriesView view = 7;
+
+  // A positive number that is the maximum number of results to return. If
+  // `page_size` is empty or more than 100,000 results, the effective
+  // `page_size` is 100,000 results. If `view` is set to `FULL`, this is the
+  // maximum number of `Points` returned. If `view` is set to `HEADERS`, this is
+  // the maximum number of `TimeSeries` returned.
+  int32 page_size = 8;
+
+  // If this field is not empty then it must contain the `nextPageToken` value
+  // returned by a previous call to this method.  Using this field causes the
+  // method to return additional results from the previous method call.
+  string page_token = 9;
+}
+
+// The `ListTimeSeries` response.
+message ListTimeSeriesResponse {
+  // One or more time series that match the filter included in the request.
+  repeated TimeSeries time_series = 1;
+
+  // If there are more results than have been returned, then this field is set
+  // to a non-empty value.  To see the additional results,
+  // use that value as `pageToken` in the next call to this method.
+  string next_page_token = 2;
+
+  // Query execution errors that may have caused the time series data returned
+  // to be incomplete.
+  repeated google.rpc.Status execution_errors = 3;
+}
+
+// The `CreateTimeSeries` request.
+message CreateTimeSeriesRequest {
+  // The project on which to execute the request. The format is
+  // `"projects/{project_id_or_number}"`.
+  string name = 3;
+
+  // The new data to be added to a list of time series.
+  // Adds at most one data point to each of several time series.  The new data
+  // point must be more recent than any other point in its time series.  Each
+  // `TimeSeries` value must fully specify a unique time series by supplying
+  // all label values for the metric and the monitored resource.
+  repeated TimeSeries time_series = 2;
+}
+
+// Describes the result of a failed request to write data to a time series.
+message CreateTimeSeriesError {
+  // The time series, including the `Metric`, `MonitoredResource`,
+  // and `Point`s (including timestamp and value) that resulted
+  // in the error. This field provides all of the context that
+  // would be needed to retry the operation.
+  TimeSeries time_series = 1;
+
+  // The status of the requested write operation.
+  google.rpc.Status status = 2;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/mutation_record.proto b/monitoring/google/cloud/monitoring_v3/proto/mutation_record.proto
new file mode 100644
index 000000000000..5f85864fe494
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/mutation_record.proto
@@ -0,0 +1,37 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "MutationRecordProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// Describes a change made to a configuration.
+message MutationRecord {
+  // When the change occurred.
+  google.protobuf.Timestamp mutate_time = 1;
+
+  // The email address of the user making the change.
+  string mutated_by = 2;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/notification.proto b/monitoring/google/cloud/monitoring_v3/proto/notification.proto
new file mode 100644
index 000000000000..ac042762d3d1
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/notification.proto
@@ -0,0 +1,164 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/annotations.proto";
+import "google/api/label.proto";
+import "google/monitoring/v3/common.proto";
+import "google/protobuf/wrappers.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "NotificationProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// A description of a notification channel. The descriptor includes
+// the properties of the channel and the set of labels or fields that
+// must be specified to configure channels of a given type.
+message NotificationChannelDescriptor {
+  // The full REST resource name for this descriptor. The syntax is:
+  //
+  //     projects/[PROJECT_ID]/notificationChannelDescriptors/[TYPE]
+  //
+  // In the above, `[TYPE]` is the value of the `type` field.
+  string name = 6;
+
+  // The type of notification channel, such as "email", "sms", etc.
+  // Notification channel types are globally unique.
+  string type = 1;
+
+  // A human-readable name for the notification channel type.  This
+  // form of the name is suitable for a user interface.
+  string display_name = 2;
+
+  // A human-readable description of the notification channel
+  // type. The description may include a description of the properties
+  // of the channel and pointers to external documentation.
+  string description = 3;
+
+  // The set of labels that must be defined to identify a particular
+  // channel of the corresponding type. Each label includes a
+  // description for how that field should be populated.
+  repeated google.api.LabelDescriptor labels = 4;
+
+  // The tiers that support this notification channel; the project service tier
+  // must be one of the supported_tiers.
+  repeated ServiceTier supported_tiers = 5 [deprecated = true];
+}
+
+// A `NotificationChannel` is a medium through which an alert is
+// delivered when a policy violation is detected. Examples of channels
+// include email, SMS, and third-party messaging applications. Fields
+// containing sensitive information like authentication tokens or
+// contact info are only partially populated on retrieval.
+message NotificationChannel {
+  // Indicates whether the channel has been verified or not. It is illegal
+  // to specify this field in a
+  // [`CreateNotificationChannel`][google.monitoring.v3.NotificationChannelService.CreateNotificationChannel]
+  // or an
+  // [`UpdateNotificationChannel`][google.monitoring.v3.NotificationChannelService.UpdateNotificationChannel]
+  // operation.
+  enum VerificationStatus {
+    // Sentinel value used to indicate that the state is unknown, omitted, or
+    // is not applicable (as in the case of channels that neither support
+    // nor require verification in order to function).
+    VERIFICATION_STATUS_UNSPECIFIED = 0;
+
+    // The channel has yet to be verified and requires verification to function.
+    // Note that this state also applies to the case where the verification
+    // process has been initiated by sending a verification code but where
+    // the verification code has not been submitted to complete the process.
+    UNVERIFIED = 1;
+
+    // It has been proven that notifications can be received on this
+    // notification channel and that someone on the project has access
+    // to messages that are delivered to that channel.
+    VERIFIED = 2;
+  }
+
+  // The type of the notification channel. This field matches the
+  // value of the [NotificationChannelDescriptor.type][google.monitoring.v3.NotificationChannelDescriptor.type] field.
+  string type = 1;
+
+  // The full REST resource name for this channel. The syntax is:
+  //
+  //     projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]
+  //
+  // The `[CHANNEL_ID]` is automatically assigned by the server on creation.
+  string name = 6;
+
+  // An optional human-readable name for this notification channel. It is
+  // recommended that you specify a non-empty and unique name in order to
+  // make it easier to identify the channels in your project, though this is
+  // not enforced. The display name is limited to 512 Unicode characters.
+  string display_name = 3;
+
+  // An optional human-readable description of this notification channel. This
+  // description may provide additional details, beyond the display
+  // name, for the channel. This may not exceeed 1024 Unicode characters.
+  string description = 4;
+
+  // Configuration fields that define the channel and its behavior. The
+  // permissible and required labels are specified in the
+  // [NotificationChannelDescriptor.labels][google.monitoring.v3.NotificationChannelDescriptor.labels] of the
+  // `NotificationChannelDescriptor` corresponding to the `type` field.
+  map<string, string> labels = 5;
+
+  // User-supplied key/value data that does not need to conform to
+  // the corresponding `NotificationChannelDescriptor`'s schema, unlike
+  // the `labels` field. This field is intended to be used for organizing
+  // and identifying the `NotificationChannel` objects.
+  //
+  // The field can contain up to 64 entries. Each key and value is limited to
+  // 63 Unicode characters or 128 bytes, whichever is smaller. Labels and
+  // values can contain only lowercase letters, numerals, underscores, and
+  // dashes. Keys must begin with a letter.
+  map<string, string> user_labels = 8;
+
+  // Indicates whether this channel has been verified or not. On a
+  // [`ListNotificationChannels`][google.monitoring.v3.NotificationChannelService.ListNotificationChannels]
+  // or
+  // [`GetNotificationChannel`][google.monitoring.v3.NotificationChannelService.GetNotificationChannel]
+  // operation, this field is expected to be populated.
+  //
+  // If the value is `UNVERIFIED`, then it indicates that the channel is
+  // non-functioning (it both requires verification and lacks verification);
+  // otherwise, it is assumed that the channel works.
+  //
+  // If the channel is neither `VERIFIED` nor `UNVERIFIED`, it implies that
+  // the channel is of a type that does not require verification or that
+  // this specific channel has been exempted from verification because it was
+  // created prior to verification being required for channels of this type.
+  //
+  // This field cannot be modified using a standard
+  // [`UpdateNotificationChannel`][google.monitoring.v3.NotificationChannelService.UpdateNotificationChannel]
+  // operation. To change the value of this field, you must call
+  // [`VerifyNotificationChannel`][google.monitoring.v3.NotificationChannelService.VerifyNotificationChannel].
+  VerificationStatus verification_status = 9;
+
+  // Whether notifications are forwarded to the described channel. This makes
+  // it possible to disable delivery of notifications to a particular channel
+  // without removing the channel from all alerting policies that reference
+  // the channel. This is a more convenient approach when the change is
+  // temporary and you want to receive notifications from the same set
+  // of alerting policies on the channel at some point in the future.
+  google.protobuf.BoolValue enabled = 11;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/notification_service.proto b/monitoring/google/cloud/monitoring_v3/proto/notification_service.proto
new file mode 100644
index 000000000000..e2c6a0ea7234
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/notification_service.proto
@@ -0,0 +1,337 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/annotations.proto";
+import "google/monitoring/v3/notification.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "NotificationServiceProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// The Notification Channel API provides access to configuration that
+// controls how messages related to incidents are sent.
+service NotificationChannelService {
+  // Lists the descriptors for supported channel types. The use of descriptors
+  // makes it possible for new channel types to be dynamically added.
+  rpc ListNotificationChannelDescriptors(ListNotificationChannelDescriptorsRequest) returns (ListNotificationChannelDescriptorsResponse) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*}/notificationChannelDescriptors"
+    };
+  }
+
+  // Gets a single channel descriptor. The descriptor indicates which fields
+  // are expected / permitted for a notification channel of the given type.
+  rpc GetNotificationChannelDescriptor(GetNotificationChannelDescriptorRequest) returns (NotificationChannelDescriptor) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*/notificationChannelDescriptors/*}"
+    };
+  }
+
+  // Lists the notification channels that have been created for the project.
+  rpc ListNotificationChannels(ListNotificationChannelsRequest) returns (ListNotificationChannelsResponse) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*}/notificationChannels"
+    };
+  }
+
+  // Gets a single notification channel. The channel includes the relevant
+  // configuration details with which the channel was created. However, the
+  // response may truncate or omit passwords, API keys, or other private key
+  // matter and thus the response may not be 100% identical to the information
+  // that was supplied in the call to the create method.
+  rpc GetNotificationChannel(GetNotificationChannelRequest) returns (NotificationChannel) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*/notificationChannels/*}"
+    };
+  }
+
+  // Creates a new notification channel, representing a single notification
+  // endpoint such as an email address, SMS number, or PagerDuty service.
+  rpc CreateNotificationChannel(CreateNotificationChannelRequest) returns (NotificationChannel) {
+    option (google.api.http) = {
+      post: "/v3/{name=projects/*}/notificationChannels"
+      body: "notification_channel"
+    };
+  }
+
+  // Updates a notification channel. Fields not specified in the field mask
+  // remain unchanged.
+  rpc UpdateNotificationChannel(UpdateNotificationChannelRequest) returns (NotificationChannel) {
+    option (google.api.http) = {
+      patch: "/v3/{notification_channel.name=projects/*/notificationChannels/*}"
+      body: "notification_channel"
+    };
+  }
+
+  // Deletes a notification channel.
+  rpc DeleteNotificationChannel(DeleteNotificationChannelRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v3/{name=projects/*/notificationChannels/*}"
+    };
+  }
+
+  // Causes a verification code to be delivered to the channel. The code
+  // can then be supplied in `VerifyNotificationChannel` to verify the channel.
+  rpc SendNotificationChannelVerificationCode(SendNotificationChannelVerificationCodeRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v3/{name=projects/*/notificationChannels/*}:sendVerificationCode"
+      body: "*"
+    };
+  }
+
+  // Requests a verification code for an already verified channel that can then
+  // be used in a call to VerifyNotificationChannel() on a different channel
+  // with an equivalent identity in the same or in a different project. This
+  // makes it possible to copy a channel between projects without requiring
+  // manual reverification of the channel. If the channel is not in the
+  // verified state, this method will fail (in other words, this may only be
+  // used if the SendNotificationChannelVerificationCode and
+  // VerifyNotificationChannel paths have already been used to put the given
+  // channel into the verified state).
+  //
+  // There is no guarantee that the verification codes returned by this method
+  // will be of a similar structure or form as the ones that are delivered
+  // to the channel via SendNotificationChannelVerificationCode; while
+  // VerifyNotificationChannel() will recognize both the codes delivered via
+  // SendNotificationChannelVerificationCode() and returned from
+  // GetNotificationChannelVerificationCode(), it is typically the case that
+  // the verification codes delivered via
+  // SendNotificationChannelVerificationCode() will be shorter and also
+  // have a shorter expiration (e.g. codes such as "G-123456") whereas
+  // GetVerificationCode() will typically return a much longer, websafe base
+  // 64 encoded string that has a longer expiration time.
+  rpc GetNotificationChannelVerificationCode(GetNotificationChannelVerificationCodeRequest) returns (GetNotificationChannelVerificationCodeResponse) {
+    option (google.api.http) = {
+      post: "/v3/{name=projects/*/notificationChannels/*}:getVerificationCode"
+      body: "*"
+    };
+  }
+
+  // Verifies a `NotificationChannel` by proving receipt of the code
+  // delivered to the channel as a result of calling
+  // `SendNotificationChannelVerificationCode`.
+  rpc VerifyNotificationChannel(VerifyNotificationChannelRequest) returns (NotificationChannel) {
+    option (google.api.http) = {
+      post: "/v3/{name=projects/*/notificationChannels/*}:verify"
+      body: "*"
+    };
+  }
+}
+
+// The `ListNotificationChannelDescriptors` request.
+message ListNotificationChannelDescriptorsRequest {
+  // The REST resource name of the parent from which to retrieve
+  // the notification channel descriptors. The expected syntax is:
+  //
+  //     projects/[PROJECT_ID]
+  //
+  // Note that this names the parent container in which to look for the
+  // descriptors; to retrieve a single descriptor by name, use the
+  // [GetNotificationChannelDescriptor][google.monitoring.v3.NotificationChannelService.GetNotificationChannelDescriptor]
+  // operation, instead.
+  string name = 4;
+
+  // The maximum number of results to return in a single response. If
+  // not set to a positive number, a reasonable value will be chosen by the
+  // service.
+  int32 page_size = 2;
+
+  // If non-empty, `page_token` must contain a value returned as the
+  // `next_page_token` in a previous response to request the next set
+  // of results.
+  string page_token = 3;
+}
+
+// The `ListNotificationChannelDescriptors` response.
+message ListNotificationChannelDescriptorsResponse {
+  // The monitored resource descriptors supported for the specified
+  // project, optionally filtered.
+  repeated NotificationChannelDescriptor channel_descriptors = 1;
+
+  // If not empty, indicates that there may be more results that match
+  // the request. Use the value in the `page_token` field in a
+  // subsequent request to fetch the next set of results. If empty,
+  // all results have been returned.
+  string next_page_token = 2;
+}
+
+// The `GetNotificationChannelDescriptor` response.
+message GetNotificationChannelDescriptorRequest {
+  // The channel type for which to execute the request. The format is
+  // `projects/[PROJECT_ID]/notificationChannelDescriptors/{channel_type}`.
+  string name = 3;
+}
+
+// The `CreateNotificationChannel` request.
+message CreateNotificationChannelRequest {
+  // The project on which to execute the request. The format is:
+  //
+  //     projects/[PROJECT_ID]
+  //
+  // Note that this names the container into which the channel will be
+  // written. This does not name the newly created channel. The resulting
+  // channel's name will have a normalized version of this field as a prefix,
+  // but will add `/notificationChannels/[CHANNEL_ID]` to identify the channel.
+  string name = 3;
+
+  // The definition of the `NotificationChannel` to create.
+  NotificationChannel notification_channel = 2;
+}
+
+// The `ListNotificationChannels` request.
+message ListNotificationChannelsRequest {
+  // The project on which to execute the request. The format is
+  // `projects/[PROJECT_ID]`. That is, this names the container
+  // in which to look for the notification channels; it does not name a
+  // specific channel. To query a specific channel by REST resource name, use
+  // the
+  // [`GetNotificationChannel`][google.monitoring.v3.NotificationChannelService.GetNotificationChannel] operation.
+  string name = 5;
+
+  // If provided, this field specifies the criteria that must be met by
+  // notification channels to be included in the response.
+  //
+  // For more details, see [sorting and
+  // filtering](/monitoring/api/v3/sorting-and-filtering).
+  string filter = 6;
+
+  // A comma-separated list of fields by which to sort the result. Supports
+  // the same set of fields as in `filter`. Entries can be prefixed with
+  // a minus sign to sort in descending rather than ascending order.
+  //
+  // For more details, see [sorting and
+  // filtering](/monitoring/api/v3/sorting-and-filtering).
+  string order_by = 7;
+
+  // The maximum number of results to return in a single response. If
+  // not set to a positive number, a reasonable value will be chosen by the
+  // service.
+  int32 page_size = 3;
+
+  // If non-empty, `page_token` must contain a value returned as the
+  // `next_page_token` in a previous response to request the next set
+  // of results.
+  string page_token = 4;
+}
+
+// The `ListNotificationChannels` response.
+message ListNotificationChannelsResponse {
+  // The notification channels defined for the specified project.
+  repeated NotificationChannel notification_channels = 3;
+
+  // If not empty, indicates that there may be more results that match
+  // the request. Use the value in the `page_token` field in a
+  // subsequent request to fetch the next set of results. If empty,
+  // all results have been returned.
+  string next_page_token = 2;
+}
+
+// The `GetNotificationChannel` request.
+message GetNotificationChannelRequest {
+  // The channel for which to execute the request. The format is
+  // `projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]`.
+  string name = 3;
+}
+
+// The `UpdateNotificationChannel` request.
+message UpdateNotificationChannelRequest {
+  // The fields to update.
+  google.protobuf.FieldMask update_mask = 2;
+
+  // A description of the changes to be applied to the specified
+  // notification channel. The description must provide a definition for
+  // fields to be updated; the names of these fields should also be
+  // included in the `update_mask`.
+  NotificationChannel notification_channel = 3;
+}
+
+// The `DeleteNotificationChannel` request.
+message DeleteNotificationChannelRequest {
+  // The channel for which to execute the request. The format is
+  // `projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]`.
+  string name = 3;
+
+  // If true, the notification channel will be deleted regardless of its
+  // use in alert policies (the policies will be updated to remove the
+  // channel). If false, channels that are still referenced by an existing
+  // alerting policy will fail to be deleted in a delete operation.
+  bool force = 5;
+}
+
+// The `SendNotificationChannelVerificationCode` request.
+message SendNotificationChannelVerificationCodeRequest {
+  // The notification channel to which to send a verification code.
+  string name = 1;
+}
+
+// The `GetNotificationChannelVerificationCode` request.
+message GetNotificationChannelVerificationCodeRequest {
+  // The notification channel for which a verification code is to be generated
+  // and retrieved. This must name a channel that is already verified; if
+  // the specified channel is not verified, the request will fail.
+  string name = 1;
+
+  // The desired expiration time. If specified, the API will guarantee that
+  // the returned code will not be valid after the specified timestamp;
+  // however, the API cannot guarantee that the returned code will be
+  // valid for at least as long as the requested time (the API puts an upper
+  // bound on the amount of time for which a code may be valid). If omitted,
+  // a default expiration will be used, which may be less than the max
+  // permissible expiration (so specifying an expiration may extend the
+  // code's lifetime over omitting an expiration, even though the API does
+  // impose an upper limit on the maximum expiration that is permitted).
+  google.protobuf.Timestamp expire_time = 2;
+}
+
+// The `GetNotificationChannelVerificationCode` request.
+message GetNotificationChannelVerificationCodeResponse {
+  // The verification code, which may be used to verify other channels
+  // that have an equivalent identity (i.e. other channels of the same
+  // type with the same fingerprint such as other email channels with
+  // the same email address or other sms channels with the same number).
+  string code = 1;
+
+  // The expiration time associated with the code that was returned. If
+  // an expiration was provided in the request, this is the minimum of the
+  // requested expiration in the request and the max permitted expiration.
+  google.protobuf.Timestamp expire_time = 2;
+}
+
+// The `VerifyNotificationChannel` request.
+message VerifyNotificationChannelRequest {
+  // The notification channel to verify.
+  string name = 1;
+
+  // The verification code that was delivered to the channel as
+  // a result of invoking the `SendNotificationChannelVerificationCode` API
+  // method or that was retrieved from a verified channel via
+  // `GetNotificationChannelVerificationCode`. For example, one might have
+  // "G-123456" or "TKNZGhhd2EyN3I1MnRnMjRv" (in general, one is only
+  // guaranteed that the code is valid UTF-8; one should not
+  // make any assumptions regarding the structure or format of the code).
+  string code = 2;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/span_context.proto b/monitoring/google/cloud/monitoring_v3/proto/span_context.proto
new file mode 100644
index 000000000000..e870d8f669cc
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/span_context.proto
@@ -0,0 +1,44 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "SpanContextProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// The context of a span, attached to google.api.Distribution.Exemplars
+// in google.api.Distribution values during aggregation.
+//
+// It contains the name of a span with format:
+//     projects/[PROJECT_ID]/traces/[TRACE_ID]/spans/[SPAN_ID]
+message SpanContext {
+  // The resource name of the span in the following format:
+  //
+  //     projects/[PROJECT_ID]/traces/[TRACE_ID]/spans/[SPAN_ID]
+  //
+  // [TRACE_ID] is a unique identifier for a trace within a project;
+  // it is a 32-character hexadecimal encoding of a 16-byte array.
+  //
+  // [SPAN_ID] is a unique identifier for a span within a trace; it
+  // is a 16-character hexadecimal encoding of an 8-byte array.
+  string span_name = 1;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/uptime.proto b/monitoring/google/cloud/monitoring_v3/proto/uptime.proto
new file mode 100644
index 000000000000..4f1b7aaa114e
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/uptime.proto
@@ -0,0 +1,272 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/monitored_resource.proto";
+import "google/protobuf/duration.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "UptimeProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// An internal checker allows uptime checks to run on private/internal GCP
+// resources.
+message InternalChecker {
+  // A unique resource name for this InternalChecker. The format is:
+  //
+  //
+  //   `projects/[PROJECT_ID]/internalCheckers/[INTERNAL_CHECKER_ID]`.
+  //
+  // PROJECT_ID is the stackdriver workspace project for the
+  // uptime check config associated with the internal checker.
+  string name = 1;
+
+  // The checker's human-readable name. The display name
+  // should be unique within a Stackdriver Workspace in order to make it easier
+  // to identify; however, uniqueness is not enforced.
+  string display_name = 2;
+
+  // The [GCP VPC network](https://cloud.google.com/vpc/docs/vpc) where the
+  // internal resource lives (ex: "default").
+  string network = 3;
+
+  // The GCP zone the uptime check should egress from. Only respected for
+  // internal uptime checks, where internal_network is specified.
+  string gcp_zone = 4;
+
+  // The GCP project_id where the internal checker lives. Not necessary
+  // the same as the workspace project.
+  string peer_project_id = 6;
+}
+
+// This message configures which resources and services to monitor for
+// availability.
+message UptimeCheckConfig {
+  // The resource submessage for group checks. It can be used instead of a
+  // monitored resource, when multiple resources are being monitored.
+  message ResourceGroup {
+    // The group of resources being monitored. Should be only the
+    // group_id, not projects/<project_id>/groups/<group_id>.
+    string group_id = 1;
+
+    // The resource type of the group members.
+    GroupResourceType resource_type = 2;
+  }
+
+  // Information involved in an HTTP/HTTPS uptime check request.
+  message HttpCheck {
+    // A type of authentication to perform against the specified resource or URL
+    // that uses username and password.
+    // Currently, only Basic authentication is supported in Uptime Monitoring.
+    message BasicAuthentication {
+      // The username to authenticate.
+      string username = 1;
+
+      // The password to authenticate.
+      string password = 2;
+    }
+
+    // If true, use HTTPS instead of HTTP to run the check.
+    bool use_ssl = 1;
+
+    // The path to the page to run the check against. Will be combined with the
+    // host (specified within the MonitoredResource) and port to construct the
+    // full URL. Optional (defaults to "/").
+    string path = 2;
+
+    // The port to the page to run the check against. Will be combined with host
+    // (specified within the MonitoredResource) and path to construct the full
+    // URL. Optional (defaults to 80 without SSL, or 443 with SSL).
+    int32 port = 3;
+
+    // The authentication information. Optional when creating an HTTP check;
+    // defaults to empty.
+    BasicAuthentication auth_info = 4;
+
+    // Boolean specifiying whether to encrypt the header information.
+    // Encryption should be specified for any headers related to authentication
+    // that you do not wish to be seen when retrieving the configuration. The
+    // server will be responsible for encrypting the headers.
+    // On Get/List calls, if mask_headers is set to True then the headers
+    // will be obscured with ******.
+    bool mask_headers = 5;
+
+    // The list of headers to send as part of the uptime check request.
+    // If two headers have the same key and different values, they should
+    // be entered as a single header, with the value being a comma-separated
+    // list of all the desired values as described at
+    // https://www.w3.org/Protocols/rfc2616/rfc2616.txt (page 31).
+    // Entering two separate headers with the same key in a Create call will
+    // cause the first to be overwritten by the second.
+    // The maximum number of headers allowed is 100.
+    map<string, string> headers = 6;
+  }
+
+  // Information required for a TCP uptime check request.
+  message TcpCheck {
+    // The port to the page to run the check against. Will be combined with host
+    // (specified within the MonitoredResource) to construct the full URL.
+    // Required.
+    int32 port = 1;
+  }
+
+  // Used to perform string matching. It allows substring and regular
+  // expressions, together with their negations.
+  message ContentMatcher {
+    // String or regex content to match (max 1024 bytes)
+    string content = 1;
+  }
+
+  // A unique resource name for this UptimeCheckConfig. The format is:
+  //
+  //
+  //   `projects/[PROJECT_ID]/uptimeCheckConfigs/[UPTIME_CHECK_ID]`.
+  //
+  // This field should be omitted when creating the uptime check configuration;
+  // on create, the resource name is assigned by the server and included in the
+  // response.
+  string name = 1;
+
+  // A human-friendly name for the uptime check configuration. The display name
+  // should be unique within a Stackdriver Workspace in order to make it easier
+  // to identify; however, uniqueness is not enforced. Required.
+  string display_name = 2;
+
+  // The resource the check is checking. Required.
+  oneof resource {
+    // The [monitored
+    // resource](https://cloud.google.com/monitoring/api/resources) associated
+    // with the configuration.
+    // The following monitored resource types are supported for uptime checks:
+    //   uptime_url
+    //   gce_instance
+    //   gae_app
+    //   aws_ec2_instance
+    //   aws_elb_load_balancer
+    google.api.MonitoredResource monitored_resource = 3;
+
+    // The group resource associated with the configuration.
+    ResourceGroup resource_group = 4;
+  }
+
+  // The type of uptime check request.
+  oneof check_request_type {
+    // Contains information needed to make an HTTP or HTTPS check.
+    HttpCheck http_check = 5;
+
+    // Contains information needed to make a TCP check.
+    TcpCheck tcp_check = 6;
+  }
+
+  // How often, in seconds, the uptime check is performed.
+  // Currently, the only supported values are `60s` (1 minute), `300s`
+  // (5 minutes), `600s` (10 minutes), and `900s` (15 minutes). Optional,
+  // defaults to `300s`.
+  google.protobuf.Duration period = 7;
+
+  // The maximum amount of time to wait for the request to complete (must be
+  // between 1 and 60 seconds). Required.
+  google.protobuf.Duration timeout = 8;
+
+  // The expected content on the page the check is run against.
+  // Currently, only the first entry in the list is supported, and other entries
+  // will be ignored. The server will look for an exact match of the string in
+  // the page response's content. This field is optional and should only be
+  // specified if a content match is required.
+  repeated ContentMatcher content_matchers = 9;
+
+  // The list of regions from which the check will be run.
+  // Some regions contain one location, and others contain more than one.
+  // If this field is specified, enough regions to include a minimum of
+  // 3 locations must be provided, or an error message is returned.
+  // Not specifying this field will result in uptime checks running from all
+  // regions.
+  repeated UptimeCheckRegion selected_regions = 10;
+
+  // If this is true, then checks are made only from the 'internal_checkers'.
+  // If it is false, then checks are made only from the 'selected_regions'.
+  // It is an error to provide 'selected_regions' when is_internal is true,
+  // or to provide 'internal_checkers' when is_internal is false.
+  bool is_internal = 15;
+
+  // The internal checkers that this check will egress from. If `is_internal` is
+  // true and this list is empty, the check will egress from all the
+  // InternalCheckers configured for the project that owns this CheckConfig.
+  repeated InternalChecker internal_checkers = 14;
+}
+
+// Contains the region, location, and list of IP
+// addresses where checkers in the location run from.
+message UptimeCheckIp {
+  // A broad region category in which the IP address is located.
+  UptimeCheckRegion region = 1;
+
+  // A more specific location within the region that typically encodes
+  // a particular city/town/metro (and its containing state/province or country)
+  // within the broader umbrella region category.
+  string location = 2;
+
+  // The IP address from which the uptime check originates. This is a full
+  // IP address (not an IP address range). Most IP addresses, as of this
+  // publication, are in IPv4 format; however, one should not rely on the
+  // IP addresses being in IPv4 format indefinitely and should support
+  // interpreting this field in either IPv4 or IPv6 format.
+  string ip_address = 3;
+}
+
+// The regions from which an uptime check can be run.
+enum UptimeCheckRegion {
+  // Default value if no region is specified. Will result in uptime checks
+  // running from all regions.
+  REGION_UNSPECIFIED = 0;
+
+  // Allows checks to run from locations within the United States of America.
+  USA = 1;
+
+  // Allows checks to run from locations within the continent of Europe.
+  EUROPE = 2;
+
+  // Allows checks to run from locations within the continent of South
+  // America.
+  SOUTH_AMERICA = 3;
+
+  // Allows checks to run from locations within the Asia Pacific area (ex:
+  // Singapore).
+  ASIA_PACIFIC = 4;
+}
+
+// The supported resource types that can be used as values of
+// `group_resource.resource_type`.
+// `INSTANCE` includes `gce_instance` and `aws_ec2_instance` resource types.
+// The resource types `gae_app` and `uptime_url` are not valid here because
+// group checks on App Engine modules and URLs are not allowed.
+enum GroupResourceType {
+  // Default value (not valid).
+  RESOURCE_TYPE_UNSPECIFIED = 0;
+
+  // A group of instances from Google Cloud Platform (GCP) or
+  // Amazon Web Services (AWS).
+  INSTANCE = 1;
+
+  // A group of Amazon ELB load balancers.
+  AWS_ELB_LOAD_BALANCER = 2;
+}
diff --git a/monitoring/google/cloud/monitoring_v3/proto/uptime_service.proto b/monitoring/google/cloud/monitoring_v3/proto/uptime_service.proto
new file mode 100644
index 000000000000..e79488332fdd
--- /dev/null
+++ b/monitoring/google/cloud/monitoring_v3/proto/uptime_service.proto
@@ -0,0 +1,203 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.monitoring.v3;
+
+import "google/api/annotations.proto";
+import "google/monitoring/v3/uptime.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+
+option csharp_namespace = "Google.Cloud.Monitoring.V3";
+option go_package = "google.golang.org/genproto/googleapis/monitoring/v3;monitoring";
+option java_multiple_files = true;
+option java_outer_classname = "UptimeServiceProto";
+option java_package = "com.google.monitoring.v3";
+option php_namespace = "Google\\Cloud\\Monitoring\\V3";
+
+
+// The UptimeCheckService API is used to manage (list, create, delete, edit)
+// uptime check configurations in the Stackdriver Monitoring product. An uptime
+// check is a piece of configuration that determines which resources and
+// services to monitor for availability. These configurations can also be
+// configured interactively by navigating to the [Cloud Console]
+// (http://console.cloud.google.com), selecting the appropriate project,
+// clicking on "Monitoring" on the left-hand side to navigate to Stackdriver,
+// and then clicking on "Uptime".
+service UptimeCheckService {
+  // Lists the existing valid uptime check configurations for the project,
+  // leaving out any invalid configurations.
+  rpc ListUptimeCheckConfigs(ListUptimeCheckConfigsRequest) returns (ListUptimeCheckConfigsResponse) {
+    option (google.api.http) = {
+      get: "/v3/{parent=projects/*}/uptimeCheckConfigs"
+    };
+  }
+
+  // Gets a single uptime check configuration.
+  rpc GetUptimeCheckConfig(GetUptimeCheckConfigRequest) returns (UptimeCheckConfig) {
+    option (google.api.http) = {
+      get: "/v3/{name=projects/*/uptimeCheckConfigs/*}"
+    };
+  }
+
+  // Creates a new uptime check configuration.
+  rpc CreateUptimeCheckConfig(CreateUptimeCheckConfigRequest) returns (UptimeCheckConfig) {
+    option (google.api.http) = {
+      post: "/v3/{parent=projects/*}/uptimeCheckConfigs"
+      body: "uptime_check_config"
+    };
+  }
+
+  // Updates an uptime check configuration. You can either replace the entire
+  // configuration with a new one or replace only certain fields in the current
+  // configuration by specifying the fields to be updated via `"updateMask"`.
+  // Returns the updated configuration.
+  rpc UpdateUptimeCheckConfig(UpdateUptimeCheckConfigRequest) returns (UptimeCheckConfig) {
+    option (google.api.http) = {
+      patch: "/v3/{uptime_check_config.name=projects/*/uptimeCheckConfigs/*}"
+      body: "uptime_check_config"
+    };
+  }
+
+  // Deletes an uptime check configuration. Note that this method will fail
+  // if the uptime check configuration is referenced by an alert policy or
+  // other dependent configs that would be rendered invalid by the deletion.
+  rpc DeleteUptimeCheckConfig(DeleteUptimeCheckConfigRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v3/{name=projects/*/uptimeCheckConfigs/*}"
+    };
+  }
+
+  // Returns the list of IPs that checkers run from
+  rpc ListUptimeCheckIps(ListUptimeCheckIpsRequest) returns (ListUptimeCheckIpsResponse) {
+    option (google.api.http) = {
+      get: "/v3/uptimeCheckIps"
+    };
+  }
+}
+
+// The protocol for the `ListUptimeCheckConfigs` request.
+message ListUptimeCheckConfigsRequest {
+  // The project whose uptime check configurations are listed. The format
+  //   is `projects/[PROJECT_ID]`.
+  string parent = 1;
+
+  // The maximum number of results to return in a single response. The server
+  // may further constrain the maximum number of results returned in a single
+  // page. If the page_size is <=0, the server will decide the number of results
+  // to be returned.
+  int32 page_size = 3;
+
+  // If this field is not empty then it must contain the `nextPageToken` value
+  // returned by a previous call to this method.  Using this field causes the
+  // method to return more results from the previous method call.
+  string page_token = 4;
+}
+
+// The protocol for the `ListUptimeCheckConfigs` response.
+message ListUptimeCheckConfigsResponse {
+  // The returned uptime check configurations.
+  repeated UptimeCheckConfig uptime_check_configs = 1;
+
+  // This field represents the pagination token to retrieve the next page of
+  // results. If the value is empty, it means no further results for the
+  // request. To retrieve the next page of results, the value of the
+  // next_page_token is passed to the subsequent List method call (in the
+  // request message's page_token field).
+  string next_page_token = 2;
+
+  // The total number of uptime check configurations for the project,
+  // irrespective of any pagination.
+  int32 total_size = 3;
+}
+
+// The protocol for the `GetUptimeCheckConfig` request.
+message GetUptimeCheckConfigRequest {
+  // The uptime check configuration to retrieve. The format
+  //   is `projects/[PROJECT_ID]/uptimeCheckConfigs/[UPTIME_CHECK_ID]`.
+  string name = 1;
+}
+
+// The protocol for the `CreateUptimeCheckConfig` request.
+message CreateUptimeCheckConfigRequest {
+  // The project in which to create the uptime check. The format
+  //   is `projects/[PROJECT_ID]`.
+  string parent = 1;
+
+  // The new uptime check configuration.
+  UptimeCheckConfig uptime_check_config = 2;
+}
+
+// The protocol for the `UpdateUptimeCheckConfig` request.
+message UpdateUptimeCheckConfigRequest {
+  // Optional. If present, only the listed fields in the current uptime check
+  // configuration are updated with values from the new configuration. If this
+  // field is empty, then the current configuration is completely replaced with
+  // the new configuration.
+  google.protobuf.FieldMask update_mask = 2;
+
+  // Required. If an `"updateMask"` has been specified, this field gives
+  // the values for the set of fields mentioned in the `"updateMask"`. If an
+  // `"updateMask"` has not been given, this uptime check configuration replaces
+  // the current configuration. If a field is mentioned in `"updateMask"` but
+  // the corresonding field is omitted in this partial uptime check
+  // configuration, it has the effect of deleting/clearing the field from the
+  // configuration on the server.
+  //
+  // The following fields can be updated: `display_name`,
+  // `http_check`, `tcp_check`, `timeout`, `content_matchers`, and
+  // `selected_regions`.
+  UptimeCheckConfig uptime_check_config = 3;
+}
+
+// The protocol for the `DeleteUptimeCheckConfig` request.
+message DeleteUptimeCheckConfigRequest {
+  // The uptime check configuration to delete. The format
+  //   is `projects/[PROJECT_ID]/uptimeCheckConfigs/[UPTIME_CHECK_ID]`.
+  string name = 1;
+}
+
+// The protocol for the `ListUptimeCheckIps` request.
+message ListUptimeCheckIpsRequest {
+  // The maximum number of results to return in a single response. The server
+  // may further constrain the maximum number of results returned in a single
+  // page. If the page_size is <=0, the server will decide the number of results
+  // to be returned.
+  // NOTE: this field is not yet implemented
+  int32 page_size = 2;
+
+  // If this field is not empty then it must contain the `nextPageToken` value
+  // returned by a previous call to this method.  Using this field causes the
+  // method to return more results from the previous method call.
+  // NOTE: this field is not yet implemented
+  string page_token = 3;
+}
+
+// The protocol for the `ListUptimeCheckIps` response.
+message ListUptimeCheckIpsResponse {
+  // The returned list of IP addresses (including region and location) that the
+  // checkers run from.
+  repeated UptimeCheckIp uptime_check_ips = 1;
+
+  // This field represents the pagination token to retrieve the next page of
+  // results. If the value is empty, it means no further results for the
+  // request. To retrieve the next page of results, the value of the
+  // next_page_token is passed to the subsequent List method call (in the
+  // request message's page_token field).
+  // NOTE: this field is not yet implemented
+  string next_page_token = 2;
+}
diff --git a/monitoring/synth.metadata b/monitoring/synth.metadata
index b9ab609dbe0b..4dc0fc943241 100644
--- a/monitoring/synth.metadata
+++ b/monitoring/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:23:25.765838Z",
+  "updateTime": "2019-01-24T05:50:25.632152Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/monitoring/synth.py b/monitoring/synth.py
index 23f0208add00..ef37a2adacee 100644
--- a/monitoring/synth.py
+++ b/monitoring/synth.py
@@ -31,6 +31,7 @@
     "v3",
     config_path="/google/monitoring/artman_monitoring.yaml",
     artman_output_name="monitoring-v3",
+    include_protos=True,
 )
 
 # don't copy nox.py, setup.py, README.rst, docs/index.rst
diff --git a/oslogin/synth.py b/oslogin/synth.py
index 551a881bc986..7e76e18b1c4e 100644
--- a/oslogin/synth.py
+++ b/oslogin/synth.py
@@ -27,6 +27,7 @@
     "v1",
     config_path="/google/cloud/oslogin/artman_oslogin_v1.yaml",
     artman_output_name="os-login-v1",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/oslogin_v1")
diff --git a/pubsub/google/cloud/pubsub_v1/proto/pubsub.proto b/pubsub/google/cloud/pubsub_v1/proto/pubsub.proto
new file mode 100644
index 000000000000..70dd1556a281
--- /dev/null
+++ b/pubsub/google/cloud/pubsub_v1/proto/pubsub.proto
@@ -0,0 +1,384 @@
+// Copyright (c) 2015, Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.pubsub.v1beta2;
+
+import "google/protobuf/empty.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/pubsub/v1beta2;pubsub";
+option java_multiple_files = true;
+option java_outer_classname = "PubsubProto";
+option java_package = "com.google.pubsub.v1beta2";
+
+
+// The service that an application uses to manipulate subscriptions and to
+// consume messages from a subscription via the Pull method.
+service Subscriber {
+  // Creates a subscription to a given topic for a given subscriber.
+  // If the subscription already exists, returns ALREADY_EXISTS.
+  // If the corresponding topic doesn't exist, returns NOT_FOUND.
+  //
+  // If the name is not provided in the request, the server will assign a random
+  // name for this subscription on the same project as the topic.
+  rpc CreateSubscription(Subscription) returns (Subscription);
+
+  // Gets the configuration details of a subscription.
+  rpc GetSubscription(GetSubscriptionRequest) returns (Subscription);
+
+  // Lists matching subscriptions.
+  rpc ListSubscriptions(ListSubscriptionsRequest) returns (ListSubscriptionsResponse);
+
+  // Deletes an existing subscription. All pending messages in the subscription
+  // are immediately dropped. Calls to Pull after deletion will return
+  // NOT_FOUND. After a subscription is deleted, a new one may be created with
+  // the same name, but the new one has no association with the old
+  // subscription, or its topic unless the same topic is specified.
+  rpc DeleteSubscription(DeleteSubscriptionRequest) returns (google.protobuf.Empty);
+
+  // Modifies the ack deadline for a specific message. This method is useful to
+  // indicate that more time is needed to process a message by the subscriber,
+  // or to make the message available for redelivery if the processing was
+  // interrupted.
+  rpc ModifyAckDeadline(ModifyAckDeadlineRequest) returns (google.protobuf.Empty);
+
+  // Acknowledges the messages associated with the ack tokens in the
+  // AcknowledgeRequest. The Pub/Sub system can remove the relevant messages
+  // from the subscription.
+  //
+  // Acknowledging a message whose ack deadline has expired may succeed,
+  // but such a message may be redelivered later. Acknowledging a message more
+  // than once will not result in an error.
+  rpc Acknowledge(AcknowledgeRequest) returns (google.protobuf.Empty);
+
+  // Pulls messages from the server. Returns an empty list if there are no
+  // messages available in the backlog. The server may return UNAVAILABLE if
+  // there are too many concurrent pull requests pending for the given
+  // subscription.
+  rpc Pull(PullRequest) returns (PullResponse);
+
+  // Modifies the PushConfig for a specified subscription.
+  //
+  // This may be used to change a push subscription to a pull one (signified
+  // by an empty PushConfig) or vice versa, or change the endpoint URL and other
+  // attributes of a push subscription. Messages will accumulate for
+  // delivery continuously through the call regardless of changes to the
+  // PushConfig.
+  rpc ModifyPushConfig(ModifyPushConfigRequest) returns (google.protobuf.Empty);
+}
+
+// The service that an application uses to manipulate topics, and to send
+// messages to a topic.
+service Publisher {
+  // Creates the given topic with the given name.
+  rpc CreateTopic(Topic) returns (Topic);
+
+  // Adds one or more messages to the topic. Returns NOT_FOUND if the topic does
+  // not exist.
+  rpc Publish(PublishRequest) returns (PublishResponse);
+
+  // Gets the configuration of a topic.
+  rpc GetTopic(GetTopicRequest) returns (Topic);
+
+  // Lists matching topics.
+  rpc ListTopics(ListTopicsRequest) returns (ListTopicsResponse);
+
+  // Lists the name of the subscriptions for this topic.
+  rpc ListTopicSubscriptions(ListTopicSubscriptionsRequest) returns (ListTopicSubscriptionsResponse);
+
+  // Deletes the topic with the given name. Returns NOT_FOUND if the topic does
+  // not exist. After a topic is deleted, a new topic may be created with the
+  // same name; this is an entirely new topic with none of the old
+  // configuration or subscriptions. Existing subscriptions to this topic are
+  // not deleted.
+  rpc DeleteTopic(DeleteTopicRequest) returns (google.protobuf.Empty);
+}
+
+// A topic resource.
+message Topic {
+  // Name of the topic.
+  string name = 1;
+}
+
+// A message data and its attributes.
+message PubsubMessage {
+  // The message payload. For JSON requests, the value of this field must be
+  // base64-encoded.
+  bytes data = 1;
+
+  // Optional attributes for this message.
+  map<string, string> attributes = 2;
+
+  // ID of this message assigned by the server at publication time. Guaranteed
+  // to be unique within the topic. This value may be read by a subscriber
+  // that receives a PubsubMessage via a Pull call or a push delivery. It must
+  // not be populated by a publisher in a Publish call.
+  string message_id = 3;
+}
+
+// Request for the GetTopic method.
+message GetTopicRequest {
+  // The name of the topic to get.
+  string topic = 1;
+}
+
+// Request for the Publish method.
+message PublishRequest {
+  // The messages in the request will be published on this topic.
+  string topic = 1;
+
+  // The messages to publish.
+  repeated PubsubMessage messages = 2;
+}
+
+// Response for the Publish method.
+message PublishResponse {
+  // The server-assigned ID of each published message, in the same order as
+  // the messages in the request. IDs are guaranteed to be unique within
+  // the topic.
+  repeated string message_ids = 1;
+}
+
+// Request for the ListTopics method.
+message ListTopicsRequest {
+  // The name of the cloud project that topics belong to.
+  string project = 1;
+
+  // Maximum number of topics to return.
+  int32 page_size = 2;
+
+  // The value returned by the last ListTopicsResponse; indicates that this is
+  // a continuation of a prior ListTopics call, and that the system should
+  // return the next page of data.
+  string page_token = 3;
+}
+
+// Response for the ListTopics method.
+message ListTopicsResponse {
+  // The resulting topics.
+  repeated Topic topics = 1;
+
+  // If not empty, indicates that there may be more topics that match the
+  // request; this value should be passed in a new ListTopicsRequest.
+  string next_page_token = 2;
+}
+
+// Request for the ListTopicSubscriptions method.
+message ListTopicSubscriptionsRequest {
+  // The name of the topic that subscriptions are attached to.
+  string topic = 1;
+
+  // Maximum number of subscription names to return.
+  int32 page_size = 2;
+
+  // The value returned by the last ListTopicSubscriptionsResponse; indicates
+  // that this is a continuation of a prior ListTopicSubscriptions call, and
+  // that the system should return the next page of data.
+  string page_token = 3;
+}
+
+// Response for the ListTopicSubscriptions method.
+message ListTopicSubscriptionsResponse {
+  // The names of the subscriptions that match the request.
+  repeated string subscriptions = 1;
+
+  // If not empty, indicates that there may be more subscriptions that match
+  // the request; this value should be passed in a new
+  // ListTopicSubscriptionsRequest to get more subscriptions.
+  string next_page_token = 2;
+}
+
+// Request for the DeleteTopic method.
+message DeleteTopicRequest {
+  // Name of the topic to delete.
+  string topic = 1;
+}
+
+// A subscription resource.
+message Subscription {
+  // Name of the subscription.
+  string name = 1;
+
+  // The name of the topic from which this subscription is receiving messages.
+  // This will be present if and only if the subscription has not been detached
+  // from its topic.
+  string topic = 2;
+
+  // If push delivery is used with this subscription, this field is
+  // used to configure it. An empty pushConfig signifies that the subscriber
+  // will pull and ack messages using API methods.
+  PushConfig push_config = 4;
+
+  // This value is the maximum time after a subscriber receives a message
+  // before the subscriber should acknowledge the message. After message
+  // delivery but before the ack deadline expires and before the message is
+  // acknowledged, it is an outstanding message and will not be delivered
+  // again during that time (on a best-effort basis).
+  //
+  // For pull delivery this value
+  // is used as the initial value for the ack deadline. It may be overridden
+  // for a specific message by calling ModifyAckDeadline.
+  //
+  // For push delivery, this value is also used to set the request timeout for
+  // the call to the push endpoint.
+  //
+  // If the subscriber never acknowledges the message, the Pub/Sub
+  // system will eventually redeliver the message.
+  int32 ack_deadline_seconds = 5;
+}
+
+// Configuration for a push delivery endpoint.
+message PushConfig {
+  // A URL locating the endpoint to which messages should be pushed.
+  // For example, a Webhook endpoint might use "https://example.com/push".
+  string push_endpoint = 1;
+
+  // Endpoint configuration attributes.
+  //
+  // Every endpoint has a set of API supported attributes that can be used to
+  // control different aspects of the message delivery.
+  //
+  // The currently supported attribute is `x-goog-version`, which you can
+  // use to change the format of the push message. This attribute
+  // indicates the version of the data expected by the endpoint. This
+  // controls the shape of the envelope (i.e. its fields and metadata).
+  // The endpoint version is based on the version of the Pub/Sub
+  // API.
+  //
+  // If not present during the CreateSubscription call, it will default to
+  // the version of the API used to make such call. If not present during a
+  // ModifyPushConfig call, its value will not be changed. GetSubscription
+  // calls will always return a valid version, even if the subscription was
+  // created without this attribute.
+  //
+  // The possible values for this attribute are:
+  //
+  // * `v1beta1`: uses the push format defined in the v1beta1 Pub/Sub API.
+  // * `v1beta2`: uses the push format defined in the v1beta2 Pub/Sub API.
+  //
+  map<string, string> attributes = 2;
+}
+
+// A message and its corresponding acknowledgment ID.
+message ReceivedMessage {
+  // This ID can be used to acknowledge the received message.
+  string ack_id = 1;
+
+  // The message.
+  PubsubMessage message = 2;
+}
+
+// Request for the GetSubscription method.
+message GetSubscriptionRequest {
+  // The name of the subscription to get.
+  string subscription = 1;
+}
+
+// Request for the ListSubscriptions method.
+message ListSubscriptionsRequest {
+  // The name of the cloud project that subscriptions belong to.
+  string project = 1;
+
+  // Maximum number of subscriptions to return.
+  int32 page_size = 2;
+
+  // The value returned by the last ListSubscriptionsResponse; indicates that
+  // this is a continuation of a prior ListSubscriptions call, and that the
+  // system should return the next page of data.
+  string page_token = 3;
+}
+
+// Response for the ListSubscriptions method.
+message ListSubscriptionsResponse {
+  // The subscriptions that match the request.
+  repeated Subscription subscriptions = 1;
+
+  // If not empty, indicates that there may be more subscriptions that match
+  // the request; this value should be passed in a new ListSubscriptionsRequest
+  // to get more subscriptions.
+  string next_page_token = 2;
+}
+
+// Request for the DeleteSubscription method.
+message DeleteSubscriptionRequest {
+  // The subscription to delete.
+  string subscription = 1;
+}
+
+// Request for the ModifyPushConfig method.
+message ModifyPushConfigRequest {
+  // The name of the subscription.
+  string subscription = 1;
+
+  // The push configuration for future deliveries.
+  //
+  // An empty pushConfig indicates that the Pub/Sub system should
+  // stop pushing messages from the given subscription and allow
+  // messages to be pulled and acknowledged - effectively pausing
+  // the subscription if Pull is not called.
+  PushConfig push_config = 2;
+}
+
+// Request for the Pull method.
+message PullRequest {
+  // The subscription from which messages should be pulled.
+  string subscription = 1;
+
+  // If this is specified as true the system will respond immediately even if
+  // it is not able to return a message in the Pull response. Otherwise the
+  // system is allowed to wait until at least one message is available rather
+  // than returning no messages. The client may cancel the request if it does
+  // not wish to wait any longer for the response.
+  bool return_immediately = 2;
+
+  // The maximum number of messages returned for this request. The Pub/Sub
+  // system may return fewer than the number specified.
+  int32 max_messages = 3;
+}
+
+// Response for the Pull method.
+message PullResponse {
+  // Received Pub/Sub messages. The Pub/Sub system will return zero messages if
+  // there are no more available in the backlog. The Pub/Sub system may return
+  // fewer than the maxMessages requested even if there are more messages
+  // available in the backlog.
+  repeated ReceivedMessage received_messages = 1;
+}
+
+// Request for the ModifyAckDeadline method.
+message ModifyAckDeadlineRequest {
+  // The name of the subscription.
+  string subscription = 1;
+
+  // The acknowledgment ID.
+  string ack_id = 2;
+
+  // The new ack deadline with respect to the time this request was sent to the
+  // Pub/Sub system. Must be >= 0. For example, if the value is 10, the new ack
+  // deadline will expire 10 seconds after the ModifyAckDeadline call was made.
+  // Specifying zero may immediately make the message available for another pull
+  // request.
+  int32 ack_deadline_seconds = 3;
+}
+
+// Request for the Acknowledge method.
+message AcknowledgeRequest {
+  // The subscription whose message is being acknowledged.
+  string subscription = 1;
+
+  // The acknowledgment ID for the messages being acknowledged that was returned
+  // by the Pub/Sub system in the Pull response. Must not be empty.
+  repeated string ack_ids = 2;
+}
diff --git a/pubsub/synth.metadata b/pubsub/synth.metadata
index a855bbbfe298..c966ed982898 100644
--- a/pubsub/synth.metadata
+++ b/pubsub/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:24:31.789706Z",
+  "updateTime": "2019-01-24T17:13:22.929911Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/pubsub/synth.py b/pubsub/synth.py
index 50fc92a07a9a..b568e148b060 100644
--- a/pubsub/synth.py
+++ b/pubsub/synth.py
@@ -27,7 +27,10 @@
 # Generate pubsub GAPIC layer
 # ----------------------------------------------------------------------------
 library = gapic.py_library(
-    "pubsub", version, config_path="/google/pubsub/artman_pubsub.yaml"
+    "pubsub",
+    version,
+    config_path="/google/pubsub/artman_pubsub.yaml",
+    include_protos=True,
 )
 s.move(
     library,
diff --git a/redis/google/cloud/redis_v1/proto/cloud_redis.proto b/redis/google/cloud/redis_v1/proto/cloud_redis.proto
new file mode 100644
index 000000000000..1aa944cdba84
--- /dev/null
+++ b/redis/google/cloud/redis_v1/proto/cloud_redis.proto
@@ -0,0 +1,340 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.redis.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/redis/v1beta1;redis";
+option java_multiple_files = true;
+option java_outer_classname = "CloudRedisServiceBetaProto";
+option java_package = "com.google.cloud.redis.v1beta1";
+
+
+// Configures and manages Cloud Memorystore for Redis instances
+//
+// Google Cloud Memorystore for Redis v1beta1
+//
+// The `redis.googleapis.com` service implements the Google Cloud Memorystore
+// for Redis API and defines the following resource model for managing Redis
+// instances:
+// * The service works with a collection of cloud projects, named: `/projects/*`
+// * Each project has a collection of available locations, named: `/locations/*`
+// * Each location has a collection of Redis instances, named: `/instances/*`
+// * As such, Redis instances are resources of the form:
+//   `/projects/{project_id}/locations/{location_id}/instances/{instance_id}`
+//
+// Note that location_id must be refering to a GCP `region`; for example:
+// * `projects/redpepper-1290/locations/us-central1/instances/my-redis`
+service CloudRedis {
+  // Lists all Redis instances owned by a project in either the specified
+  // location (region) or all locations.
+  //
+  // The location should have the following format:
+  // * `projects/{project_id}/locations/{location_id}`
+  //
+  // If `location_id` is specified as `-` (wildcard), then all regions
+  // available to the project are queried, and the results are aggregated.
+  rpc ListInstances(ListInstancesRequest) returns (ListInstancesResponse) {
+    option (google.api.http) = {
+      get: "/v1beta1/{parent=projects/*/locations/*}/instances"
+    };
+  }
+
+  // Gets the details of a specific Redis instance.
+  rpc GetInstance(GetInstanceRequest) returns (Instance) {
+    option (google.api.http) = {
+      get: "/v1beta1/{name=projects/*/locations/*/instances/*}"
+    };
+  }
+
+  // Creates a Redis instance based on the specified tier and memory size.
+  //
+  // By default, the instance is peered to the project's
+  // [default network](/compute/docs/networks-and-firewalls#networks).
+  //
+  // The creation is executed asynchronously and callers may check the returned
+  // operation to track its progress. Once the operation is completed the Redis
+  // instance will be fully functional. Completed longrunning.Operation will
+  // contain the new instance object in the response field.
+  //
+  // The returned operation is automatically deleted after a few hours, so there
+  // is no need to call DeleteOperation.
+  rpc CreateInstance(CreateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=projects/*/locations/*}/instances"
+      body: "instance"
+    };
+  }
+
+  // Updates the metadata and configuration of a specific Redis instance.
+  //
+  // Completed longrunning.Operation will contain the new instance object
+  // in the response field. The returned operation is automatically deleted
+  // after a few hours, so there is no need to call DeleteOperation.
+  rpc UpdateInstance(UpdateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v1beta1/{instance.name=projects/*/locations/*/instances/*}"
+      body: "instance"
+    };
+  }
+
+  // Deletes a specific Redis instance.  Instance stops serving and data is
+  // deleted.
+  rpc DeleteInstance(DeleteInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      delete: "/v1beta1/{name=projects/*/locations/*/instances/*}"
+    };
+  }
+}
+
+// A Google Cloud Redis instance.
+message Instance {
+  // Represents the different states of a Redis instance.
+  enum State {
+    // Not set.
+    STATE_UNSPECIFIED = 0;
+
+    // Redis instance is being created.
+    CREATING = 1;
+
+    // Redis instance has been created and is fully usable.
+    READY = 2;
+
+    // Redis instance configuration is being updated. Certain kinds of updates
+    // may cause the instance to become unusable while the update is in
+    // progress.
+    UPDATING = 3;
+
+    // Redis instance is being deleted.
+    DELETING = 4;
+
+    // Redis instance is being repaired and may be unusable. Details can be
+    // found in the `status_message` field.
+    REPAIRING = 5;
+
+    // Maintenance is being performed on this Redis instance.
+    MAINTENANCE = 6;
+  }
+
+  // Available service tiers to choose from
+  enum Tier {
+    // Not set.
+    TIER_UNSPECIFIED = 0;
+
+    // BASIC tier: standalone instance
+    BASIC = 1;
+
+    // STANDARD_HA tier: highly available primary/replica instances
+    STANDARD_HA = 3;
+  }
+
+  // Required. Unique name of the resource in this scope including project and
+  // location using the form:
+  //     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
+  //
+  // Note: Redis instances are managed and addressed at regional level so
+  // location_id here refers to a GCP region; however, users get to choose which
+  // specific zone (or collection of zones for cross-zone instances) an instance
+  // should be provisioned in. Refer to [location_id] and
+  // [alternative_location_id] fields for more details.
+  string name = 1;
+
+  // An arbitrary and optional user-provided name for the instance.
+  string display_name = 2;
+
+  // Resource labels to represent user provided metadata
+  map<string, string> labels = 3;
+
+  // Optional. The zone where the instance will be provisioned. If not provided,
+  // the service will choose a zone for the instance. For STANDARD_HA tier,
+  // instances will be created across two zones for protection against zonal
+  // failures. if [alternative_location_id] is also provided, it must be
+  // different from [location_id].
+  string location_id = 4;
+
+  // Optional. Only applicable to STANDARD_HA tier which protects the instance
+  // against zonal failures by provisioning it across two zones. If provided, it
+  // must be a different zone from the one provided in [location_id].
+  string alternative_location_id = 5;
+
+  // Optional. The version of Redis software.
+  // If not provided, latest supported version will be used.
+  string redis_version = 7;
+
+  // Optional. The CIDR range of internal addresses that are reserved for this
+  // instance. If not provided, the service will choose an unused /29 block,
+  // for example, 10.0.0.0/29 or 192.168.0.0/29. Ranges must be unique
+  // and non-overlapping with existing subnets in a network.
+  string reserved_ip_range = 9;
+
+  // Output only. Hostname or IP address of the exposed redis endpoint used by
+  // clients to connect to the service.
+  string host = 10;
+
+  // Output only. The port number of the exposed redis endpoint.
+  int32 port = 11;
+
+  // Output only. The current zone where the Redis endpoint is placed. In
+  // single zone deployments, this will always be the same as [location_id]
+  // provided by the user at creation time. In cross-zone instances (only
+  // applicable in STANDARD_HA tier), this can be either [location_id] or
+  // [alternative_location_id] and can change on a failover event.
+  string current_location_id = 12;
+
+  // Output only. The time the instance was created.
+  google.protobuf.Timestamp create_time = 13;
+
+  // Output only. The current state of this instance.
+  State state = 14;
+
+  // Output only. Additional information about the current status of this
+  // instance, if available.
+  string status_message = 15;
+
+  // Optional. Redis configuration parameters, according to
+  // http://redis.io/topics/config. Currently, the only supported parameters
+  // are:
+  //  * maxmemory-policy
+  //  * notify-keyspace-events
+  map<string, string> redis_configs = 16;
+
+  // Required. The service tier of the instance.
+  Tier tier = 17;
+
+  // Required. Redis memory size in GB.
+  int32 memory_size_gb = 18;
+
+  // Optional. The full name of the Google Compute Engine
+  // [network](/compute/docs/networks-and-firewalls#networks) to which the
+  // instance is connected. If left unspecified, the `default` network
+  // will be used.
+  string authorized_network = 20;
+}
+
+// Request for [ListInstances][google.cloud.redis.v1beta1.CloudRedis.ListInstances].
+message ListInstancesRequest {
+  // Required. The resource name of the instance location using the form:
+  //     `projects/{project_id}/locations/{location_id}`
+  // where `location_id` refers to a GCP region
+  string parent = 1;
+
+  // The maximum number of items to return.
+  //
+  // If not specified, a default value of 1000 will be used by the service.
+  // Regardless of the page_size value, the response may include a partial list
+  // and a caller should only rely on response's
+  // [next_page_token][CloudRedis.ListInstancesResponse.next_page_token]
+  // to determine if there are more instances left to be queried.
+  int32 page_size = 2;
+
+  // The next_page_token value returned from a previous List request,
+  // if any.
+  string page_token = 3;
+}
+
+// Response for [ListInstances][google.cloud.redis.v1beta1.CloudRedis.ListInstances].
+message ListInstancesResponse {
+  // A list of Redis instances in the project in the specified location,
+  // or across all locations.
+  //
+  // If the `location_id` in the parent field of the request is "-", all regions
+  // available to the project are queried, and the results aggregated.
+  // If in such an aggregated query a location is unavailable, a dummy Redis
+  // entry is included in the response with the "name" field set to a value of
+  // the form projects/{project_id}/locations/{location_id}/instances/- and the
+  // "status" field set to ERROR and "status_message" field set to "location not
+  // available for ListInstances".
+  repeated Instance instances = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// Request for [GetInstance][google.cloud.redis.v1beta1.CloudRedis.GetInstance].
+message GetInstanceRequest {
+  // Required. Redis instance resource name using the form:
+  //     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
+  // where `location_id` refers to a GCP region
+  string name = 1;
+}
+
+// Request for [CreateInstance][google.cloud.redis.v1beta1.CloudRedis.CreateInstance].
+message CreateInstanceRequest {
+  // Required. The resource name of the instance location using the form:
+  //     `projects/{project_id}/locations/{location_id}`
+  // where `location_id` refers to a GCP region
+  string parent = 1;
+
+  // Required. The logical name of the Redis instance in the customer project
+  // with the following restrictions:
+  //
+  // * Must contain only lowercase letters, numbers, and hyphens.
+  // * Must start with a letter.
+  // * Must be between 1-40 characters.
+  // * Must end with a number or a letter.
+  // * Must be unique within the customer project / location
+  string instance_id = 2;
+
+  // Required. A Redis [Instance] resource
+  Instance instance = 3;
+}
+
+// Request for [UpdateInstance][google.cloud.redis.v1beta1.CloudRedis.UpdateInstance].
+message UpdateInstanceRequest {
+  // Required. Mask of fields to update. At least one path must be supplied in
+  // this field. The elements of the repeated paths field may only include these
+  // fields from [Instance][CloudRedis.Instance]:
+  // * `display_name`
+  // * `labels`
+  // * `memory_size_gb`
+  // * `redis_config`
+  google.protobuf.FieldMask update_mask = 1;
+
+  // Required. Update description.
+  // Only fields specified in update_mask are updated.
+  Instance instance = 2;
+}
+
+// Request for [DeleteInstance][google.cloud.redis.v1beta1.CloudRedis.DeleteInstance].
+message DeleteInstanceRequest {
+  // Required. Redis instance resource name using the form:
+  //     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
+  // where `location_id` refers to a GCP region
+  string name = 1;
+}
+
+// This location metadata represents additional configuration options for a
+// given location where a Redis instance may be created. All fields are output
+// only. It is returned as content of the
+// `google.cloud.location.Location.metadata` field.
+message LocationMetadata {
+  // Output only. The set of available zones in the location. The map is keyed
+  // by the lowercase ID of each zone, as defined by GCE. These keys can be
+  // specified in `location_id` or `alternative_location_id` fields when
+  // creating a Redis instance.
+  map<string, ZoneMetadata> available_zones = 1;
+}
+
+// Defines specific information for a particular zone. Currently empty and
+// reserved for future use only.
+message ZoneMetadata {
+
+}
diff --git a/redis/google/cloud/redis_v1beta1/proto/cloud_redis.proto b/redis/google/cloud/redis_v1beta1/proto/cloud_redis.proto
new file mode 100644
index 000000000000..1aa944cdba84
--- /dev/null
+++ b/redis/google/cloud/redis_v1beta1/proto/cloud_redis.proto
@@ -0,0 +1,340 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.redis.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/redis/v1beta1;redis";
+option java_multiple_files = true;
+option java_outer_classname = "CloudRedisServiceBetaProto";
+option java_package = "com.google.cloud.redis.v1beta1";
+
+
+// Configures and manages Cloud Memorystore for Redis instances
+//
+// Google Cloud Memorystore for Redis v1beta1
+//
+// The `redis.googleapis.com` service implements the Google Cloud Memorystore
+// for Redis API and defines the following resource model for managing Redis
+// instances:
+// * The service works with a collection of cloud projects, named: `/projects/*`
+// * Each project has a collection of available locations, named: `/locations/*`
+// * Each location has a collection of Redis instances, named: `/instances/*`
+// * As such, Redis instances are resources of the form:
+//   `/projects/{project_id}/locations/{location_id}/instances/{instance_id}`
+//
+// Note that location_id must be refering to a GCP `region`; for example:
+// * `projects/redpepper-1290/locations/us-central1/instances/my-redis`
+service CloudRedis {
+  // Lists all Redis instances owned by a project in either the specified
+  // location (region) or all locations.
+  //
+  // The location should have the following format:
+  // * `projects/{project_id}/locations/{location_id}`
+  //
+  // If `location_id` is specified as `-` (wildcard), then all regions
+  // available to the project are queried, and the results are aggregated.
+  rpc ListInstances(ListInstancesRequest) returns (ListInstancesResponse) {
+    option (google.api.http) = {
+      get: "/v1beta1/{parent=projects/*/locations/*}/instances"
+    };
+  }
+
+  // Gets the details of a specific Redis instance.
+  rpc GetInstance(GetInstanceRequest) returns (Instance) {
+    option (google.api.http) = {
+      get: "/v1beta1/{name=projects/*/locations/*/instances/*}"
+    };
+  }
+
+  // Creates a Redis instance based on the specified tier and memory size.
+  //
+  // By default, the instance is peered to the project's
+  // [default network](/compute/docs/networks-and-firewalls#networks).
+  //
+  // The creation is executed asynchronously and callers may check the returned
+  // operation to track its progress. Once the operation is completed the Redis
+  // instance will be fully functional. Completed longrunning.Operation will
+  // contain the new instance object in the response field.
+  //
+  // The returned operation is automatically deleted after a few hours, so there
+  // is no need to call DeleteOperation.
+  rpc CreateInstance(CreateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=projects/*/locations/*}/instances"
+      body: "instance"
+    };
+  }
+
+  // Updates the metadata and configuration of a specific Redis instance.
+  //
+  // Completed longrunning.Operation will contain the new instance object
+  // in the response field. The returned operation is automatically deleted
+  // after a few hours, so there is no need to call DeleteOperation.
+  rpc UpdateInstance(UpdateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v1beta1/{instance.name=projects/*/locations/*/instances/*}"
+      body: "instance"
+    };
+  }
+
+  // Deletes a specific Redis instance.  Instance stops serving and data is
+  // deleted.
+  rpc DeleteInstance(DeleteInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      delete: "/v1beta1/{name=projects/*/locations/*/instances/*}"
+    };
+  }
+}
+
+// A Google Cloud Redis instance.
+message Instance {
+  // Represents the different states of a Redis instance.
+  enum State {
+    // Not set.
+    STATE_UNSPECIFIED = 0;
+
+    // Redis instance is being created.
+    CREATING = 1;
+
+    // Redis instance has been created and is fully usable.
+    READY = 2;
+
+    // Redis instance configuration is being updated. Certain kinds of updates
+    // may cause the instance to become unusable while the update is in
+    // progress.
+    UPDATING = 3;
+
+    // Redis instance is being deleted.
+    DELETING = 4;
+
+    // Redis instance is being repaired and may be unusable. Details can be
+    // found in the `status_message` field.
+    REPAIRING = 5;
+
+    // Maintenance is being performed on this Redis instance.
+    MAINTENANCE = 6;
+  }
+
+  // Available service tiers to choose from
+  enum Tier {
+    // Not set.
+    TIER_UNSPECIFIED = 0;
+
+    // BASIC tier: standalone instance
+    BASIC = 1;
+
+    // STANDARD_HA tier: highly available primary/replica instances
+    STANDARD_HA = 3;
+  }
+
+  // Required. Unique name of the resource in this scope including project and
+  // location using the form:
+  //     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
+  //
+  // Note: Redis instances are managed and addressed at regional level so
+  // location_id here refers to a GCP region; however, users get to choose which
+  // specific zone (or collection of zones for cross-zone instances) an instance
+  // should be provisioned in. Refer to [location_id] and
+  // [alternative_location_id] fields for more details.
+  string name = 1;
+
+  // An arbitrary and optional user-provided name for the instance.
+  string display_name = 2;
+
+  // Resource labels to represent user provided metadata
+  map<string, string> labels = 3;
+
+  // Optional. The zone where the instance will be provisioned. If not provided,
+  // the service will choose a zone for the instance. For STANDARD_HA tier,
+  // instances will be created across two zones for protection against zonal
+  // failures. if [alternative_location_id] is also provided, it must be
+  // different from [location_id].
+  string location_id = 4;
+
+  // Optional. Only applicable to STANDARD_HA tier which protects the instance
+  // against zonal failures by provisioning it across two zones. If provided, it
+  // must be a different zone from the one provided in [location_id].
+  string alternative_location_id = 5;
+
+  // Optional. The version of Redis software.
+  // If not provided, latest supported version will be used.
+  string redis_version = 7;
+
+  // Optional. The CIDR range of internal addresses that are reserved for this
+  // instance. If not provided, the service will choose an unused /29 block,
+  // for example, 10.0.0.0/29 or 192.168.0.0/29. Ranges must be unique
+  // and non-overlapping with existing subnets in a network.
+  string reserved_ip_range = 9;
+
+  // Output only. Hostname or IP address of the exposed redis endpoint used by
+  // clients to connect to the service.
+  string host = 10;
+
+  // Output only. The port number of the exposed redis endpoint.
+  int32 port = 11;
+
+  // Output only. The current zone where the Redis endpoint is placed. In
+  // single zone deployments, this will always be the same as [location_id]
+  // provided by the user at creation time. In cross-zone instances (only
+  // applicable in STANDARD_HA tier), this can be either [location_id] or
+  // [alternative_location_id] and can change on a failover event.
+  string current_location_id = 12;
+
+  // Output only. The time the instance was created.
+  google.protobuf.Timestamp create_time = 13;
+
+  // Output only. The current state of this instance.
+  State state = 14;
+
+  // Output only. Additional information about the current status of this
+  // instance, if available.
+  string status_message = 15;
+
+  // Optional. Redis configuration parameters, according to
+  // http://redis.io/topics/config. Currently, the only supported parameters
+  // are:
+  //  * maxmemory-policy
+  //  * notify-keyspace-events
+  map<string, string> redis_configs = 16;
+
+  // Required. The service tier of the instance.
+  Tier tier = 17;
+
+  // Required. Redis memory size in GB.
+  int32 memory_size_gb = 18;
+
+  // Optional. The full name of the Google Compute Engine
+  // [network](/compute/docs/networks-and-firewalls#networks) to which the
+  // instance is connected. If left unspecified, the `default` network
+  // will be used.
+  string authorized_network = 20;
+}
+
+// Request for [ListInstances][google.cloud.redis.v1beta1.CloudRedis.ListInstances].
+message ListInstancesRequest {
+  // Required. The resource name of the instance location using the form:
+  //     `projects/{project_id}/locations/{location_id}`
+  // where `location_id` refers to a GCP region
+  string parent = 1;
+
+  // The maximum number of items to return.
+  //
+  // If not specified, a default value of 1000 will be used by the service.
+  // Regardless of the page_size value, the response may include a partial list
+  // and a caller should only rely on response's
+  // [next_page_token][CloudRedis.ListInstancesResponse.next_page_token]
+  // to determine if there are more instances left to be queried.
+  int32 page_size = 2;
+
+  // The next_page_token value returned from a previous List request,
+  // if any.
+  string page_token = 3;
+}
+
+// Response for [ListInstances][google.cloud.redis.v1beta1.CloudRedis.ListInstances].
+message ListInstancesResponse {
+  // A list of Redis instances in the project in the specified location,
+  // or across all locations.
+  //
+  // If the `location_id` in the parent field of the request is "-", all regions
+  // available to the project are queried, and the results aggregated.
+  // If in such an aggregated query a location is unavailable, a dummy Redis
+  // entry is included in the response with the "name" field set to a value of
+  // the form projects/{project_id}/locations/{location_id}/instances/- and the
+  // "status" field set to ERROR and "status_message" field set to "location not
+  // available for ListInstances".
+  repeated Instance instances = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// Request for [GetInstance][google.cloud.redis.v1beta1.CloudRedis.GetInstance].
+message GetInstanceRequest {
+  // Required. Redis instance resource name using the form:
+  //     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
+  // where `location_id` refers to a GCP region
+  string name = 1;
+}
+
+// Request for [CreateInstance][google.cloud.redis.v1beta1.CloudRedis.CreateInstance].
+message CreateInstanceRequest {
+  // Required. The resource name of the instance location using the form:
+  //     `projects/{project_id}/locations/{location_id}`
+  // where `location_id` refers to a GCP region
+  string parent = 1;
+
+  // Required. The logical name of the Redis instance in the customer project
+  // with the following restrictions:
+  //
+  // * Must contain only lowercase letters, numbers, and hyphens.
+  // * Must start with a letter.
+  // * Must be between 1-40 characters.
+  // * Must end with a number or a letter.
+  // * Must be unique within the customer project / location
+  string instance_id = 2;
+
+  // Required. A Redis [Instance] resource
+  Instance instance = 3;
+}
+
+// Request for [UpdateInstance][google.cloud.redis.v1beta1.CloudRedis.UpdateInstance].
+message UpdateInstanceRequest {
+  // Required. Mask of fields to update. At least one path must be supplied in
+  // this field. The elements of the repeated paths field may only include these
+  // fields from [Instance][CloudRedis.Instance]:
+  // * `display_name`
+  // * `labels`
+  // * `memory_size_gb`
+  // * `redis_config`
+  google.protobuf.FieldMask update_mask = 1;
+
+  // Required. Update description.
+  // Only fields specified in update_mask are updated.
+  Instance instance = 2;
+}
+
+// Request for [DeleteInstance][google.cloud.redis.v1beta1.CloudRedis.DeleteInstance].
+message DeleteInstanceRequest {
+  // Required. Redis instance resource name using the form:
+  //     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
+  // where `location_id` refers to a GCP region
+  string name = 1;
+}
+
+// This location metadata represents additional configuration options for a
+// given location where a Redis instance may be created. All fields are output
+// only. It is returned as content of the
+// `google.cloud.location.Location.metadata` field.
+message LocationMetadata {
+  // Output only. The set of available zones in the location. The map is keyed
+  // by the lowercase ID of each zone, as defined by GCE. These keys can be
+  // specified in `location_id` or `alternative_location_id` fields when
+  // creating a Redis instance.
+  map<string, ZoneMetadata> available_zones = 1;
+}
+
+// Defines specific information for a particular zone. Currently empty and
+// reserved for future use only.
+message ZoneMetadata {
+
+}
diff --git a/redis/synth.metadata b/redis/synth.metadata
index 9af1673794b6..6c1b4d45d92e 100644
--- a/redis/synth.metadata
+++ b/redis/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:25:14.294829Z",
+  "updateTime": "2019-01-24T17:19:20.924756Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/redis/synth.py b/redis/synth.py
index 067dc96047fb..b569680461f3 100644
--- a/redis/synth.py
+++ b/redis/synth.py
@@ -29,7 +29,10 @@
 # ----------------------------------------------------------------------------
 for version in ["v1beta1", "v1"]:
     library = gapic.py_library(
-        "redis", version, config_path=f"artman_redis_{version}.yaml"
+        "redis",
+        version,
+        config_path=f"artman_redis_{version}.yaml",
+        include_protos=True,
     )
 
     s.copy(library, excludes=excludes)
diff --git a/scheduler/google/cloud/scheduler_v1beta1/proto/cloudscheduler.proto b/scheduler/google/cloud/scheduler_v1beta1/proto/cloudscheduler.proto
new file mode 100644
index 000000000000..f3fa89dcf36a
--- /dev/null
+++ b/scheduler/google/cloud/scheduler_v1beta1/proto/cloudscheduler.proto
@@ -0,0 +1,237 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.scheduler.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/scheduler/v1beta1/job.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1;scheduler";
+option java_multiple_files = true;
+option java_outer_classname = "SchedulerProto";
+option java_package = "com.google.cloud.scheduler.v1beta1";
+option objc_class_prefix = "SCHEDULER";
+
+
+// The Cloud Scheduler API allows external entities to reliably
+// schedule asynchronous jobs.
+service CloudScheduler {
+  // Lists jobs.
+  rpc ListJobs(ListJobsRequest) returns (ListJobsResponse) {
+    option (google.api.http) = {
+      get: "/v1beta1/{parent=projects/*/locations/*}/jobs"
+    };
+  }
+
+  // Gets a job.
+  rpc GetJob(GetJobRequest) returns (Job) {
+    option (google.api.http) = {
+      get: "/v1beta1/{name=projects/*/locations/*/jobs/*}"
+    };
+  }
+
+  // Creates a job.
+  rpc CreateJob(CreateJobRequest) returns (Job) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=projects/*/locations/*}/jobs"
+      body: "job"
+    };
+  }
+
+  // Updates a job.
+  //
+  // If successful, the updated [Job][google.cloud.scheduler.v1beta1.Job] is returned. If the job does
+  // not exist, `NOT_FOUND` is returned.
+  //
+  // If UpdateJob does not successfully return, it is possible for the
+  // job to be in an [Job.State.UPDATE_FAILED][google.cloud.scheduler.v1beta1.Job.State.UPDATE_FAILED] state. A job in this state may
+  // not be executed. If this happens, retry the UpdateJob request
+  // until a successful response is received.
+  rpc UpdateJob(UpdateJobRequest) returns (Job) {
+    option (google.api.http) = {
+      patch: "/v1beta1/{job.name=projects/*/locations/*/jobs/*}"
+      body: "job"
+    };
+  }
+
+  // Deletes a job.
+  rpc DeleteJob(DeleteJobRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1beta1/{name=projects/*/locations/*/jobs/*}"
+    };
+  }
+
+  // Pauses a job.
+  //
+  // If a job is paused then the system will stop executing the job
+  // until it is re-enabled via [ResumeJob][google.cloud.scheduler.v1beta1.CloudScheduler.ResumeJob]. The
+  // state of the job is stored in [state][google.cloud.scheduler.v1beta1.Job.state]; if paused it
+  // will be set to [Job.State.PAUSED][google.cloud.scheduler.v1beta1.Job.State.PAUSED]. A job must be in [Job.State.ENABLED][google.cloud.scheduler.v1beta1.Job.State.ENABLED]
+  // to be paused.
+  rpc PauseJob(PauseJobRequest) returns (Job) {
+    option (google.api.http) = {
+      post: "/v1beta1/{name=projects/*/locations/*/jobs/*}:pause"
+      body: "*"
+    };
+  }
+
+  // Resume a job.
+  //
+  // This method reenables a job after it has been [Job.State.PAUSED][google.cloud.scheduler.v1beta1.Job.State.PAUSED]. The
+  // state of a job is stored in [Job.state][google.cloud.scheduler.v1beta1.Job.state]; after calling this method it
+  // will be set to [Job.State.ENABLED][google.cloud.scheduler.v1beta1.Job.State.ENABLED]. A job must be in
+  // [Job.State.PAUSED][google.cloud.scheduler.v1beta1.Job.State.PAUSED] to be resumed.
+  rpc ResumeJob(ResumeJobRequest) returns (Job) {
+    option (google.api.http) = {
+      post: "/v1beta1/{name=projects/*/locations/*/jobs/*}:resume"
+      body: "*"
+    };
+  }
+
+  // Forces a job to run now.
+  //
+  // When this method is called, Cloud Scheduler will dispatch the job, even
+  // if the job is already running.
+  rpc RunJob(RunJobRequest) returns (Job) {
+    option (google.api.http) = {
+      post: "/v1beta1/{name=projects/*/locations/*/jobs/*}:run"
+      body: "*"
+    };
+  }
+}
+
+// Request message for listing jobs using [ListJobs][google.cloud.scheduler.v1beta1.CloudScheduler.ListJobs].
+message ListJobsRequest {
+  // Required.
+  //
+  // The location name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID`.
+  string parent = 1;
+
+  // Requested page size.
+  //
+  // The maximum page size is 500. If unspecified, the page size will
+  // be the maximum. Fewer jobs than requested might be returned,
+  // even if more jobs exist; use next_page_token to determine if more
+  // jobs exist.
+  int32 page_size = 5;
+
+  // A token identifying a page of results the server will return. To
+  // request the first page results, page_token must be empty. To
+  // request the next page of results, page_token must be the value of
+  // [next_page_token][google.cloud.scheduler.v1beta1.ListJobsResponse.next_page_token] returned from
+  // the previous call to [ListJobs][google.cloud.scheduler.v1beta1.CloudScheduler.ListJobs]. It is an error to
+  // switch the value of [filter][google.cloud.scheduler.v1beta1.ListJobsRequest.filter] or
+  // [order_by][google.cloud.scheduler.v1beta1.ListJobsRequest.order_by] while iterating through pages.
+  string page_token = 6;
+}
+
+// Response message for listing jobs using [ListJobs][google.cloud.scheduler.v1beta1.CloudScheduler.ListJobs].
+message ListJobsResponse {
+  // The list of jobs.
+  repeated Job jobs = 1;
+
+  // A token to retrieve next page of results. Pass this value in the
+  // [page_token][google.cloud.scheduler.v1beta1.ListJobsRequest.page_token] field in the subsequent call to
+  // [ListJobs][google.cloud.scheduler.v1beta1.CloudScheduler.ListJobs] to retrieve the next page of results.
+  // If this is empty it indicates that there are no more results
+  // through which to paginate.
+  //
+  // The page token is valid for only 2 hours.
+  string next_page_token = 2;
+}
+
+// Request message for [GetJob][google.cloud.scheduler.v1beta1.CloudScheduler.GetJob].
+message GetJobRequest {
+  // Required.
+  //
+  // The job name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/jobs/JOB_ID`.
+  string name = 1;
+}
+
+// Request message for [CreateJob][google.cloud.scheduler.v1beta1.CloudScheduler.CreateJob].
+message CreateJobRequest {
+  // Required.
+  //
+  // The location name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID`.
+  string parent = 1;
+
+  // Required.
+  //
+  // The job to add. The user can optionally specify a name for the
+  // job in [name][google.cloud.scheduler.v1beta1.Job.name]. [name][google.cloud.scheduler.v1beta1.Job.name] cannot be the same as an
+  // existing job. If a name is not specified then the system will
+  // generate a random unique name that will be returned
+  // ([name][google.cloud.scheduler.v1beta1.Job.name]) in the response.
+  Job job = 2;
+}
+
+// Request message for [UpdateJob][google.cloud.scheduler.v1beta1.CloudScheduler.UpdateJob].
+message UpdateJobRequest {
+  // Required.
+  //
+  // The new job properties. [name][google.cloud.scheduler.v1beta1.Job.name] must be specified.
+  //
+  // Output only fields cannot be modified using UpdateJob.
+  // Any value specified for an output only field will be ignored.
+  Job job = 1;
+
+  // A  mask used to specify which fields of the job are being updated.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for deleting a job using
+// [DeleteJob][google.cloud.scheduler.v1beta1.CloudScheduler.DeleteJob].
+message DeleteJobRequest {
+  // Required.
+  //
+  // The job name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/jobs/JOB_ID`.
+  string name = 1;
+}
+
+// Request message for [PauseJob][google.cloud.scheduler.v1beta1.CloudScheduler.PauseJob].
+message PauseJobRequest {
+  // Required.
+  //
+  // The job name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/jobs/JOB_ID`.
+  string name = 1;
+}
+
+// Request message for [ResumeJob][google.cloud.scheduler.v1beta1.CloudScheduler.ResumeJob].
+message ResumeJobRequest {
+  // Required.
+  //
+  // The job name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/jobs/JOB_ID`.
+  string name = 1;
+}
+
+// Request message for forcing a job to run now using
+// [RunJob][google.cloud.scheduler.v1beta1.CloudScheduler.RunJob].
+message RunJobRequest {
+  // Required.
+  //
+  // The job name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/jobs/JOB_ID`.
+  string name = 1;
+}
diff --git a/scheduler/google/cloud/scheduler_v1beta1/proto/job.proto b/scheduler/google/cloud/scheduler_v1beta1/proto/job.proto
new file mode 100644
index 000000000000..32fea587bc4e
--- /dev/null
+++ b/scheduler/google/cloud/scheduler_v1beta1/proto/job.proto
@@ -0,0 +1,212 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.scheduler.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/scheduler/v1beta1/target.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1;scheduler";
+option java_multiple_files = true;
+option java_outer_classname = "JobProto";
+option java_package = "com.google.cloud.scheduler.v1beta1";
+
+
+// Configuration for a job.
+// The maximum allowed size for a job is 100KB.
+message Job {
+  // State of the job.
+  enum State {
+    // Unspecified state.
+    STATE_UNSPECIFIED = 0;
+
+    // The job is executing normally.
+    ENABLED = 1;
+
+    // The job is paused by the user. It will not execute. A user can
+    // intentionally pause the job using
+    // [PauseJobRequest][google.cloud.scheduler.v1beta1.PauseJobRequest].
+    PAUSED = 2;
+
+    // The job is disabled by the system due to error. The user
+    // cannot directly set a job to be disabled.
+    DISABLED = 3;
+
+    // The job state resulting from a failed [CloudScheduler.UpdateJob][google.cloud.scheduler.v1beta1.CloudScheduler.UpdateJob]
+    // operation. To recover a job from this state, retry
+    // [CloudScheduler.UpdateJob][google.cloud.scheduler.v1beta1.CloudScheduler.UpdateJob] until a successful response is received.
+    UPDATE_FAILED = 4;
+  }
+
+  // The job name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/jobs/JOB_ID`.
+  //
+  // * `PROJECT_ID` can contain letters ([A-Za-z]), numbers ([0-9]),
+  //    hyphens (-), colons (:), or periods (.).
+  //    For more information, see
+  //    [Identifying projects](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects)
+  // * `LOCATION_ID` is the canonical ID for the job's location.
+  //    The list of available locations can be obtained by calling
+  //    [ListLocations][google.cloud.location.Locations.ListLocations].
+  //    For more information, see https://cloud.google.com/about/locations/.
+  // * `JOB_ID` can contain only letters ([A-Za-z]), numbers ([0-9]),
+  //    hyphens (-), or underscores (_). The maximum length is 500 characters.
+  string name = 1;
+
+  // A human-readable description for the job. This string must not contain
+  // more than 500 characters.
+  string description = 2;
+
+  // Required.
+  //
+  // Delivery settings containing destination and parameters.
+  oneof target {
+    // Pub/Sub target.
+    PubsubTarget pubsub_target = 4;
+
+    // App Engine HTTP target.
+    AppEngineHttpTarget app_engine_http_target = 5;
+
+    // HTTP target.
+    HttpTarget http_target = 6;
+  }
+
+  // Required.
+  //
+  // Describes the schedule on which the job will be executed.
+  //
+  // As a general rule, execution `n + 1` of a job will not begin
+  // until execution `n` has finished. Cloud Scheduler will never
+  // allow two simultaneously outstanding executions. For example,
+  // this implies that if the `n+1`th execution is scheduled to run at
+  // 16:00 but the `n`th execution takes until 16:15, the `n+1`th
+  // execution will not start until `16:15`.
+  // A scheduled start time will be delayed if the previous
+  // execution has not ended when its scheduled time occurs.
+  //
+  // If [retry_count][google.cloud.scheduler.v1beta1.RetryConfig.retry_count] > 0 and a job attempt fails,
+  // the job will be tried a total of [retry_count][google.cloud.scheduler.v1beta1.RetryConfig.retry_count]
+  // times, with exponential backoff, until the next scheduled start
+  // time.
+  //
+  // The schedule can be either of the following types:
+  //
+  // * [Crontab](http://en.wikipedia.org/wiki/Cron#Overview)
+  // * English-like [schedule](https://cloud.google.com/scheduler/docs/configuring/cron-job-schedules)
+  string schedule = 20;
+
+  // Specifies the time zone to be used in interpreting
+  // [schedule][google.cloud.scheduler.v1beta1.Job.schedule]. The value of this field must be a time
+  // zone name from the [tz database](http://en.wikipedia.org/wiki/Tz_database).
+  //
+  // Note that some time zones include a provision for
+  // daylight savings time. The rules for daylight saving time are
+  // determined by the chosen tz. For UTC use the string "utc". If a
+  // time zone is not specified, the default will be in UTC (also known
+  // as GMT).
+  string time_zone = 21;
+
+  // Output only. The creation time of the job.
+  google.protobuf.Timestamp user_update_time = 9;
+
+  // Output only. State of the job.
+  State state = 10;
+
+  // Output only. The response from the target for the last attempted execution.
+  google.rpc.Status status = 11;
+
+  // Output only. The next time the job is scheduled. Note that this may be a
+  // retry of a previously failed attempt or the next execution time
+  // according to the schedule.
+  google.protobuf.Timestamp schedule_time = 17;
+
+  // Output only. The time the last job attempt started.
+  google.protobuf.Timestamp last_attempt_time = 18;
+
+  // Settings that determine the retry behavior.
+  RetryConfig retry_config = 19;
+}
+
+// Settings that determine the retry behavior.
+//
+// By default, if a job does not complete successfully (meaning that
+// an acknowledgement is not received from the handler, then it will be retried
+// with exponential backoff according to the settings in [RetryConfig][google.cloud.scheduler.v1beta1.RetryConfig].
+message RetryConfig {
+  // The number of attempts that the system will make to run a job using the
+  // exponential backoff procedure described by
+  // [max_doublings][google.cloud.scheduler.v1beta1.RetryConfig.max_doublings].
+  //
+  // The default value of retry_count is zero.
+  //
+  // If retry_count is zero, a job attempt will *not* be retried if
+  // it fails. Instead the Cloud Scheduler system will wait for the
+  // next scheduled execution time.
+  //
+  // If retry_count is set to a non-zero number then Cloud Scheduler
+  // will retry failed attempts, using exponential backoff,
+  // retry_count times, or until the next scheduled execution time,
+  // whichever comes first.
+  //
+  // Values greater than 5 and negative values are not allowed.
+  int32 retry_count = 1;
+
+  // The time limit for retrying a failed job, measured from time when an
+  // execution was first attempted. If specified with
+  // [retry_count][google.cloud.scheduler.v1beta1.RetryConfig.retry_count], the job will be retried until both limits are
+  // reached.
+  //
+  // The default value for max_retry_duration is zero, which means retry
+  // duration is unlimited.
+  google.protobuf.Duration max_retry_duration = 2;
+
+  // The minimum amount of time to wait before retrying a job after
+  // it fails.
+  //
+  // The default value of this field is 5 seconds.
+  google.protobuf.Duration min_backoff_duration = 3;
+
+  // The maximum amount of time to wait before retrying a job after
+  // it fails.
+  //
+  // The default value of this field is 1 hour.
+  google.protobuf.Duration max_backoff_duration = 4;
+
+  // The time between retries will double `max_doublings` times.
+  //
+  // A job's retry interval starts at
+  // [min_backoff_duration][google.cloud.scheduler.v1beta1.RetryConfig.min_backoff_duration], then doubles
+  // `max_doublings` times, then increases linearly, and finally
+  // retries retries at intervals of
+  // [max_backoff_duration][google.cloud.scheduler.v1beta1.RetryConfig.max_backoff_duration] up to
+  // [retry_count][google.cloud.scheduler.v1beta1.RetryConfig.retry_count] times.
+  //
+  // For example, if [min_backoff_duration][google.cloud.scheduler.v1beta1.RetryConfig.min_backoff_duration] is
+  // 10s, [max_backoff_duration][google.cloud.scheduler.v1beta1.RetryConfig.max_backoff_duration] is 300s, and
+  // `max_doublings` is 3, then the a job will first be retried in 10s. The
+  // retry interval will double three times, and then increase linearly by
+  // 2^3 * 10s.  Finally, the job will retry at intervals of
+  // [max_backoff_duration][google.cloud.scheduler.v1beta1.RetryConfig.max_backoff_duration] until the job has
+  // been attempted [retry_count][google.cloud.scheduler.v1beta1.RetryConfig.retry_count] times. Thus, the
+  // requests will retry at 10s, 20s, 40s, 80s, 160s, 240s, 300s, 300s, ....
+  //
+  // The default value of this field is 5.
+  int32 max_doublings = 5;
+}
diff --git a/scheduler/google/cloud/scheduler_v1beta1/proto/target.proto b/scheduler/google/cloud/scheduler_v1beta1/proto/target.proto
new file mode 100644
index 000000000000..210002e32a20
--- /dev/null
+++ b/scheduler/google/cloud/scheduler_v1beta1/proto/target.proto
@@ -0,0 +1,285 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.scheduler.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/any.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1;scheduler";
+option java_multiple_files = true;
+option java_outer_classname = "TargetProto";
+option java_package = "com.google.cloud.scheduler.v1beta1";
+
+
+// Http target. The job will be pushed to the job handler by means of
+// an HTTP request via an [http_method][google.cloud.scheduler.v1beta1.HttpTarget.http_method] such as HTTP
+// POST, HTTP GET, etc. The job is acknowledged by means of an HTTP
+// response code in the range [200 - 299]. A failure to receive a response
+// constitutes a failed execution. For a redirected request, the response
+// returned by the redirected request is considered.
+message HttpTarget {
+  // Required.
+  //
+  // The full URI path that the request will be sent to. This string
+  // must begin with either "http://" or "https://". Some examples of
+  // valid values for [uri][google.cloud.scheduler.v1beta1.HttpTarget.uri] are:
+  // `http://acme.com` and `https://acme.com/sales:8080`. Cloud Scheduler will
+  // encode some characters for safety and compatibility. The maximum allowed
+  // URL length is 2083 characters after encoding.
+  string uri = 1;
+
+  // Which HTTP method to use for the request.
+  HttpMethod http_method = 2;
+
+  // The user can specify HTTP request headers to send with the job's
+  // HTTP request. This map contains the header field names and
+  // values. Repeated headers are not supported, but a header value can
+  // contain commas. These headers represent a subset of the headers
+  // that will accompany the job's HTTP request. Some HTTP request
+  // headers will be ignored or replaced. A partial list of headers that
+  // will be ignored or replaced is below:
+  // - Host: This will be computed by Cloud Scheduler and derived from
+  // [uri][google.cloud.scheduler.v1beta1.HttpTarget.uri].
+  // * `Content-Length`: This will be computed by Cloud Scheduler.
+  // * `User-Agent`: This will be set to `"Google-Cloud-Scheduler"`.
+  // * `X-Google-*`: Google internal use only.
+  // * `X-AppEngine-*`: Google internal use only.
+  //
+  // The total size of headers must be less than 80KB.
+  map<string, string> headers = 3;
+
+  // HTTP request body. A request body is allowed only if the HTTP
+  // method is POST, PUT, or PATCH. It is an error to set body on a job with an
+  // incompatible [HttpMethod][google.cloud.scheduler.v1beta1.HttpMethod].
+  bytes body = 4;
+}
+
+// App Engine target. The job will be pushed to a job handler by means
+// of an HTTP request via an [http_method][google.cloud.scheduler.v1beta1.AppEngineHttpTarget.http_method] such
+// as HTTP POST, HTTP GET, etc. The job is acknowledged by means of an
+// HTTP response code in the range [200 - 299]. Error 503 is
+// considered an App Engine system error instead of an application
+// error. Requests returning error 503 will be retried regardless of
+// retry configuration and not counted against retry counts. Any other
+// response code, or a failure to receive a response before the
+// deadline, constitutes a failed attempt.
+message AppEngineHttpTarget {
+  // The HTTP method to use for the request. PATCH and OPTIONS are not
+  // permitted.
+  HttpMethod http_method = 1;
+
+  // App Engine Routing setting for the job.
+  AppEngineRouting app_engine_routing = 2;
+
+  // The relative URI.
+  //
+  // The relative URL must begin with "/" and must be a valid HTTP relative URL.
+  // It can contain a path, query string arguments, and `#` fragments.
+  // If the relative URL is empty, then the root path "/" will be used.
+  // No spaces are allowed, and the maximum length allowed is 2083 characters.
+  string relative_uri = 3;
+
+  // HTTP request headers.
+  //
+  // This map contains the header field names and values. Headers can be set
+  // when the job is created.
+  //
+  // Cloud Scheduler sets some headers to default values:
+  //
+  // * `User-Agent`: By default, this header is
+  //   `"AppEngine-Google; (+http://code.google.com/appengine)"`.
+  //   This header can be modified, but Cloud Scheduler will append
+  //   `"AppEngine-Google; (+http://code.google.com/appengine)"` to the
+  //   modified `User-Agent`.
+  //
+  // If the job has an [body][google.cloud.scheduler.v1beta1.AppEngineHttpTarget.body], Cloud Scheduler sets the
+  // following headers:
+  //
+  // * `Content-Type`: By default, the `Content-Type` header is set to
+  //   `"application/octet-stream"`. The default can be overridden by explictly
+  //   setting `Content-Type` to a particular media type when the job is
+  //   created.
+  //   For example, `Content-Type` can be set to `"application/json"`.
+  // * `Content-Length`: This is computed by Cloud Scheduler. This value is
+  //   output only. It cannot be changed.
+  //
+  // The headers below are output only. They cannot be set or overridden:
+  //
+  // * `X-Google-*`: For Google internal use only.
+  // * `X-AppEngine-*`: For Google internal use only. See
+  //   [Reading request headers](https://cloud.google.com/appengine/docs/python/taskqueue/push/creating-handlers#reading_request_headers).
+  //
+  // In addition, some App Engine headers, which contain
+  // job-specific information, are also be sent to the job handler; see
+  // [request headers](https://cloud.google.com/appengine/docs/standard/python/config/cron#securing_urls_for_cron).
+  map<string, string> headers = 4;
+
+  // Body.
+  //
+  // HTTP request body. A request body is allowed only if the HTTP method is
+  // POST or PUT. It will result in invalid argument error to set a body on a
+  // job with an incompatible [HttpMethod][google.cloud.scheduler.v1beta1.HttpMethod].
+  bytes body = 5;
+}
+
+// Pub/Sub target. The job will be delivered by publishing a message to
+// the given Pub/Sub topic.
+message PubsubTarget {
+  // Required.
+  //
+  // The name of the Cloud Pub/Sub topic to which messages will
+  // be published when a job is delivered. The topic name must be in the
+  // same format as required by PubSub's
+  // [PublishRequest.name](https://cloud.google.com/pubsub/docs/reference/rpc/google.pubsub.v1#publishrequest),
+  // for example `projects/PROJECT_ID/topics/TOPIC_ID`.
+  //
+  // The topic must be in the same project as the Cloud Scheduler job.
+  string topic_name = 1;
+
+  // The message payload for PubsubMessage.
+  //
+  // Pubsub message must contain either non-empty data, or at least one
+  // attribute.
+  bytes data = 3;
+
+  // Attributes for PubsubMessage.
+  //
+  // Pubsub message must contain either non-empty data, or at least one
+  // attribute.
+  map<string, string> attributes = 4;
+}
+
+// App Engine Routing.
+//
+// For more information about services, versions, and instances see
+// [An Overview of App Engine](https://cloud.google.com/appengine/docs/python/an-overview-of-app-engine),
+// [Microservices Architecture on Google App Engine](https://cloud.google.com/appengine/docs/python/microservices-on-app-engine),
+// [App Engine Standard request routing](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed), and
+// [App Engine Flex request routing](https://cloud.google.com/appengine/docs/flexible/python/how-requests-are-routed).
+message AppEngineRouting {
+  // App service.
+  //
+  // By default, the job is sent to the service which is the default
+  // service when the job is attempted.
+  string service = 1;
+
+  // App version.
+  //
+  // By default, the job is sent to the version which is the default
+  // version when the job is attempted.
+  string version = 2;
+
+  // App instance.
+  //
+  // By default, the job is sent to an instance which is available when
+  // the job is attempted.
+  //
+  // Requests can only be sent to a specific instance if
+  // [manual scaling is used in App Engine Standard](https://cloud.google.com/appengine/docs/python/an-overview-of-app-engine?hl=en_US#scaling_types_and_instance_classes).
+  // App Engine Flex does not support instances. For more information, see
+  // [App Engine Standard request routing](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed) and
+  // [App Engine Flex request routing](https://cloud.google.com/appengine/docs/flexible/python/how-requests-are-routed).
+  string instance = 3;
+
+  // Output only. The host that the job is sent to.
+  //
+  // For more information about how App Engine requests are routed, see
+  // [here](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed).
+  //
+  // The host is constructed as:
+  //
+  //
+  // * `host = [application_domain_name]`</br>
+  //   `| [service] + '.' + [application_domain_name]`</br>
+  //   `| [version] + '.' + [application_domain_name]`</br>
+  //   `| [version_dot_service]+ '.' + [application_domain_name]`</br>
+  //   `| [instance] + '.' + [application_domain_name]`</br>
+  //   `| [instance_dot_service] + '.' + [application_domain_name]`</br>
+  //   `| [instance_dot_version] + '.' + [application_domain_name]`</br>
+  //   `| [instance_dot_version_dot_service] + '.' + [application_domain_name]`
+  //
+  // * `application_domain_name` = The domain name of the app, for
+  //   example <app-id>.appspot.com, which is associated with the
+  //   job's project ID.
+  //
+  // * `service =` [service][google.cloud.scheduler.v1beta1.AppEngineRouting.service]
+  //
+  // * `version =` [version][google.cloud.scheduler.v1beta1.AppEngineRouting.version]
+  //
+  // * `version_dot_service =`
+  //   [version][google.cloud.scheduler.v1beta1.AppEngineRouting.version] `+ '.' +`
+  //   [service][google.cloud.scheduler.v1beta1.AppEngineRouting.service]
+  //
+  // * `instance =` [instance][google.cloud.scheduler.v1beta1.AppEngineRouting.instance]
+  //
+  // * `instance_dot_service =`
+  //   [instance][google.cloud.scheduler.v1beta1.AppEngineRouting.instance] `+ '.' +`
+  //   [service][google.cloud.scheduler.v1beta1.AppEngineRouting.service]
+  //
+  // * `instance_dot_version =`
+  //   [instance][google.cloud.scheduler.v1beta1.AppEngineRouting.instance] `+ '.' +`
+  //   [version][google.cloud.scheduler.v1beta1.AppEngineRouting.version]
+  //
+  // * `instance_dot_version_dot_service =`
+  //   [instance][google.cloud.scheduler.v1beta1.AppEngineRouting.instance] `+ '.' +`
+  //   [version][google.cloud.scheduler.v1beta1.AppEngineRouting.version] `+ '.' +`
+  //   [service][google.cloud.scheduler.v1beta1.AppEngineRouting.service]
+  //
+  //
+  // If [service][google.cloud.scheduler.v1beta1.AppEngineRouting.service] is empty, then the job will be sent
+  // to the service which is the default service when the job is attempted.
+  //
+  // If [version][google.cloud.scheduler.v1beta1.AppEngineRouting.version] is empty, then the job will be sent
+  // to the version which is the default version when the job is attempted.
+  //
+  // If [instance][google.cloud.scheduler.v1beta1.AppEngineRouting.instance] is empty, then the job will be
+  // sent to an instance which is available when the job is attempted.
+  //
+  // If [service][google.cloud.scheduler.v1beta1.AppEngineRouting.service],
+  // [version][google.cloud.scheduler.v1beta1.AppEngineRouting.version], or
+  // [instance][google.cloud.scheduler.v1beta1.AppEngineRouting.instance] is invalid, then the job will be sent
+  // to the default version of the default service when the job is attempted.
+  string host = 4;
+}
+
+// The HTTP method used to execute the job.
+enum HttpMethod {
+  // HTTP method unspecified. Defaults to POST.
+  HTTP_METHOD_UNSPECIFIED = 0;
+
+  // HTTP POST
+  POST = 1;
+
+  // HTTP GET
+  GET = 2;
+
+  // HTTP HEAD
+  HEAD = 3;
+
+  // HTTP PUT
+  PUT = 4;
+
+  // HTTP DELETE
+  DELETE = 5;
+
+  // HTTP PATCH
+  PATCH = 6;
+
+  // HTTP OPTIONS
+  OPTIONS = 7;
+}
diff --git a/scheduler/synth.metadata b/scheduler/synth.metadata
index a134a9d1d728..883e45a0385e 100644
--- a/scheduler/synth.metadata
+++ b/scheduler/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:25:42.975797Z",
+  "updateTime": "2019-01-24T17:24:25.393279Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/scheduler/synth.py b/scheduler/synth.py
index f0e1dde5877a..bbed7d215352 100644
--- a/scheduler/synth.py
+++ b/scheduler/synth.py
@@ -32,6 +32,7 @@
     "v1beta1",
     config_path="artman_cloudscheduler_v1beta1.yaml",
     artman_output_name="cloudscheduler-v1beta1",
+    include_protos=True,
 )
 
 excludes = ["README.rst", "nox.py", "setup.py", "docs/conf.py", "docs/index.rst"]
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/asset.proto b/securitycenter/google/cloud/securitycenter_v1beta1/proto/asset.proto
new file mode 100644
index 000000000000..3dd5b358141d
--- /dev/null
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/asset.proto
@@ -0,0 +1,86 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.securitycenter.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/securitycenter/v1beta1/security_marks.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/securitycenter/v1beta1;securitycenter";
+option java_multiple_files = true;
+option java_package = "com.google.cloud.securitycenter.v1beta1";
+
+// Cloud Security Command Center's (Cloud SCC) representation of a Google Cloud
+// Platform (GCP) resource.
+//
+// The Asset is a Cloud SCC resource that captures information about a single
+// GCP resource. All modifications to an Asset are only within the context of
+// Cloud SCC and don't affect the referenced GCP resource.
+message Asset {
+  // Cloud SCC managed properties. These properties are managed by Cloud SCC and
+  // cannot be modified by the user.
+  message SecurityCenterProperties {
+    // The full resource name of the GCP resource this asset
+    // represents. This field is immutable after create time. See:
+    // https://cloud.google.com/apis/design/resource_names#full_resource_name
+    string resource_name = 1;
+
+    // The type of the GCP resource. Examples include: APPLICATION,
+    // PROJECT, and ORGANIZATION. This is a case insensitive field defined by
+    // Cloud SCC and/or the producer of the resource and is immutable
+    // after create time.
+    string resource_type = 2;
+
+    // The full resource name of the immediate parent of the resource. See:
+    // https://cloud.google.com/apis/design/resource_names#full_resource_name
+    string resource_parent = 3;
+
+    // The full resource name of the project the resource belongs to. See:
+    // https://cloud.google.com/apis/design/resource_names#full_resource_name
+    string resource_project = 4;
+
+    // Owners of the Google Cloud resource.
+    repeated string resource_owners = 5;
+  }
+
+  // The relative resource name of this asset. See:
+  // https://cloud.google.com/apis/design/resource_names#relative_resource_name
+  // Example:
+  // "organizations/123/assets/456".
+  string name = 1;
+
+  // Cloud SCC managed properties. These properties are managed by
+  // Cloud SCC and cannot be modified by the user.
+  SecurityCenterProperties security_center_properties = 2;
+
+  // Resource managed properties. These properties are managed and defined by
+  // the GCP resource and cannot be modified by the user.
+  map<string, google.protobuf.Value> resource_properties = 7;
+
+  // User specified security marks. These marks are entirely managed by the user
+  // and come from the SecurityMarks resource that belongs to the asset.
+  SecurityMarks security_marks = 8;
+
+  // The time at which the asset was created in Cloud SCC.
+  google.protobuf.Timestamp create_time = 9;
+
+  // The time at which the asset was last updated, added, or deleted in Cloud
+  // SCC.
+  google.protobuf.Timestamp update_time = 10;
+}
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/asset_pb2.py b/securitycenter/google/cloud/securitycenter_v1beta1/proto/asset_pb2.py
index fc37a148ba90..731547f80d06 100644
--- a/securitycenter/google/cloud/securitycenter_v1beta1/proto/asset_pb2.py
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/asset_pb2.py
@@ -452,3 +452,4 @@
 DESCRIPTOR._options = None
 _ASSET_RESOURCEPROPERTIESENTRY._options = None
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/finding.proto b/securitycenter/google/cloud/securitycenter_v1beta1/proto/finding.proto
new file mode 100644
index 000000000000..21dfdd5616e2
--- /dev/null
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/finding.proto
@@ -0,0 +1,99 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.securitycenter.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/securitycenter/v1beta1/security_marks.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/securitycenter/v1beta1;securitycenter";
+option java_multiple_files = true;
+option java_package = "com.google.cloud.securitycenter.v1beta1";
+
+// Cloud Security Command Center (Cloud SCC) finding.
+//
+// A finding is a record of assessment data (security, risk, health or privacy)
+// ingested into Cloud SCC for presentation, notification, analysis,
+// policy testing, and enforcement. For example, an XSS vulnerability in an
+// App Engine application is a finding.
+message Finding {
+  // The state of the finding.
+  enum State {
+    // Unspecified state.
+    STATE_UNSPECIFIED = 0;
+
+    // The finding requires attention and has not been addressed yet.
+    ACTIVE = 1;
+
+    // The finding has been fixed, triaged as a non-issue or otherwise addressed
+    // and is no longer active.
+    INACTIVE = 2;
+  }
+
+  // The relative resource name of this finding. See:
+  // https://cloud.google.com/apis/design/resource_names#relative_resource_name
+  // Example:
+  // "organizations/123/sources/456/findings/789"
+  string name = 1;
+
+  // The relative resource name of the source the finding belongs to. See:
+  // https://cloud.google.com/apis/design/resource_names#relative_resource_name
+  // This field is immutable after creation time.
+  // For example:
+  // "organizations/123/sources/456"
+  string parent = 2;
+
+  // The full resource name of the Google Cloud Platform (GCP) resource this
+  // finding is for. See:
+  // https://cloud.google.com/apis/design/resource_names#full_resource_name
+  // This field is immutable after creation time.
+  string resource_name = 3;
+
+  // The state of the finding.
+  State state = 4;
+
+  // The additional taxonomy group within findings from a given source.
+  // This field is immutable after creation time.
+  // Example: "XSS_FLASH_INJECTION"
+  string category = 5;
+
+  // The URI that, if available, points to a web page outside of Cloud SCC
+  // where additional information about the finding can be found. This field is
+  // guaranteed to be either empty or a well formed URL.
+  string external_uri = 6;
+
+  // Source specific properties. These properties are managed by the source
+  // that writes the finding. The key names in the source_properties map must be
+  // between 1 and 255 characters, and must start with a letter and contain
+  // alphanumeric characters or underscores only.
+  map<string, google.protobuf.Value> source_properties = 7;
+
+  // Output only. User specified security marks. These marks are entirely
+  // managed by the user and come from the SecurityMarks resource that belongs
+  // to the finding.
+  SecurityMarks security_marks = 8;
+
+  // The time at which the event took place. For example, if the finding
+  // represents an open firewall it would capture the time the open firewall was
+  // detected.
+  google.protobuf.Timestamp event_time = 9;
+
+  // The time at which the finding was created in Cloud SCC.
+  google.protobuf.Timestamp create_time = 10;
+}
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/finding_pb2.py b/securitycenter/google/cloud/securitycenter_v1beta1/proto/finding_pb2.py
index a85a20232890..84b1fddb2252 100644
--- a/securitycenter/google/cloud/securitycenter_v1beta1/proto/finding_pb2.py
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/finding_pb2.py
@@ -425,3 +425,4 @@
 DESCRIPTOR._options = None
 _FINDING_SOURCEPROPERTIESENTRY._options = None
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/organization_settings.proto b/securitycenter/google/cloud/securitycenter_v1beta1/proto/organization_settings.proto
new file mode 100644
index 000000000000..cc9f1c3ce3e4
--- /dev/null
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/organization_settings.proto
@@ -0,0 +1,75 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.securitycenter.v1beta1;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/securitycenter/v1beta1;securitycenter";
+option java_multiple_files = true;
+option java_package = "com.google.cloud.securitycenter.v1beta1";
+
+
+// User specified settings that are attached to the Cloud Security Command
+// Center (Cloud SCC) organization.
+message OrganizationSettings {
+  // The configuration used for Asset Discovery runs.
+  message AssetDiscoveryConfig {
+    // The mode of inclusion when running Asset Discovery.
+    // Asset discovery can be limited by explicitly identifying projects to be
+    // included or excluded. If INCLUDE_ONLY is set, then only those projects
+    // within the organization and their children are discovered during asset
+    // discovery. If EXCLUDE is set, then projects that don't match those
+    // projects are discovered during asset discovery. If neither are set, then
+    // all projects within the organization are discovered during asset
+    // discovery.
+    enum InclusionMode {
+      // Unspecified. Setting the mode with this value will disable
+      // inclusion/exclusion filtering for Asset Discovery.
+      INCLUSION_MODE_UNSPECIFIED = 0;
+
+      // Asset Discovery will capture only the resources within the projects
+      // specified. All other resources will be ignored.
+      INCLUDE_ONLY = 1;
+
+      // Asset Discovery will ignore all resources under the projects specified.
+      // All other resources will be retrieved.
+      EXCLUDE = 2;
+    }
+
+    // The project ids to use for filtering asset discovery.
+    repeated string project_ids = 1;
+
+    // The mode to use for filtering asset discovery.
+    InclusionMode inclusion_mode = 2;
+  }
+
+  // The relative resource name of the settings. See:
+  // https://cloud.google.com/apis/design/resource_names#relative_resource_name
+  // Example:
+  // "organizations/123/organizationSettings".
+  string name = 1;
+
+  // A flag that indicates if Asset Discovery should be enabled. If the flag is
+  // set to `true`, then discovery of assets will occur. If it is set to `false,
+  // all historical assets will remain, but discovery of future assets will not
+  // occur.
+  bool enable_asset_discovery = 2;
+
+  // The configuration used for Asset Discovery runs.
+  AssetDiscoveryConfig asset_discovery_config = 3;
+}
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/organization_settings_pb2.py b/securitycenter/google/cloud/securitycenter_v1beta1/proto/organization_settings_pb2.py
index e7c1588af71e..429a09afa73a 100644
--- a/securitycenter/google/cloud/securitycenter_v1beta1/proto/organization_settings_pb2.py
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/organization_settings_pb2.py
@@ -253,3 +253,4 @@
 
 DESCRIPTOR._options = None
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/security_marks.proto b/securitycenter/google/cloud/securitycenter_v1beta1/proto/security_marks.proto
new file mode 100644
index 000000000000..02eb9ed23f7a
--- /dev/null
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/security_marks.proto
@@ -0,0 +1,46 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.securitycenter.v1beta1;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/securitycenter/v1beta1;securitycenter";
+option java_multiple_files = true;
+option java_package = "com.google.cloud.securitycenter.v1beta1";
+
+
+// User specified security marks that are attached to the parent Cloud Security
+// Command Center (Cloud SCC) resource. Security marks are scoped within a Cloud
+// SCC organization -- they can be modified and viewed by all users who have
+// proper permissions on the organization.
+message SecurityMarks {
+  // The relative resource name of the SecurityMarks. See:
+  // https://cloud.google.com/apis/design/resource_names#relative_resource_name
+  // Examples:
+  // "organizations/123/assets/456/securityMarks"
+  // "organizations/123/sources/456/findings/789/securityMarks".
+  string name = 1;
+
+  // Mutable user specified security marks belonging to the parent resource.
+  // Constraints are as follows:
+  //   - Keys and values are treated as case insensitive
+  //   - Keys must be alphanumeric and between 1 - 256 characters (inclusive)
+  //   - Values have leading and trailing whitespace trimmed, remaining
+  //     characters must be between 1 - 4096 characters (inclusive)
+  map<string, string> marks = 2;
+}
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/security_marks_pb2.py b/securitycenter/google/cloud/securitycenter_v1beta1/proto/security_marks_pb2.py
index dcee636baff8..8f872f1b9bc7 100644
--- a/securitycenter/google/cloud/securitycenter_v1beta1/proto/security_marks_pb2.py
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/security_marks_pb2.py
@@ -194,3 +194,4 @@
 DESCRIPTOR._options = None
 _SECURITYMARKS_MARKSENTRY._options = None
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/securitycenter_service.proto b/securitycenter/google/cloud/securitycenter_v1beta1/proto/securitycenter_service.proto
new file mode 100644
index 000000000000..dafce562dc7e
--- /dev/null
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/securitycenter_service.proto
@@ -0,0 +1,755 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.securitycenter.v1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/securitycenter/v1beta1/asset.proto";
+import "google/cloud/securitycenter/v1beta1/finding.proto";
+import "google/cloud/securitycenter/v1beta1/organization_settings.proto";
+import "google/cloud/securitycenter/v1beta1/security_marks.proto";
+import "google/cloud/securitycenter/v1beta1/source.proto";
+import "google/iam/v1/iam_policy.proto";
+import "google/iam/v1/policy.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/securitycenter/v1beta1;securitycenter";
+option java_multiple_files = true;
+option java_package = "com.google.cloud.securitycenter.v1beta1";
+
+// V1 Beta APIs for Security Center service.
+service SecurityCenter {
+  // Creates a source.
+  rpc CreateSource(CreateSourceRequest) returns (Source) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=organizations/*}/sources"
+      body: "source"
+    };
+  }
+
+  // Creates a finding. The corresponding source must exist for finding creation
+  // to succeed.
+  rpc CreateFinding(CreateFindingRequest) returns (Finding) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=organizations/*/sources/*}/findings"
+      body: "finding"
+    };
+  }
+
+  // Gets the access control policy on the specified Source.
+  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest)
+      returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1beta1/{resource=organizations/*/sources/*}:getIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Gets the settings for an organization.
+  rpc GetOrganizationSettings(GetOrganizationSettingsRequest)
+      returns (OrganizationSettings) {
+    option (google.api.http) = {
+      get: "/v1beta1/{name=organizations/*/organizationSettings}"
+    };
+  }
+
+  // Gets a source.
+  rpc GetSource(GetSourceRequest) returns (Source) {
+    option (google.api.http) = {
+      get: "/v1beta1/{name=organizations/*/sources/*}"
+    };
+  }
+
+  // Filters an organization's assets and  groups them by their specified
+  // properties.
+  rpc GroupAssets(GroupAssetsRequest) returns (GroupAssetsResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=organizations/*}/assets:group"
+      body: "*"
+    };
+  }
+
+  // Filters an organization or source's findings and  groups them by their
+  // specified properties.
+  //
+  // To group across all sources provide a `-` as the source id.
+  // Example: /v1beta1/organizations/123/sources/-/findings
+  rpc GroupFindings(GroupFindingsRequest) returns (GroupFindingsResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=organizations/*/sources/*}/findings:group"
+      body: "*"
+    };
+  }
+
+  // Lists an organization's assets.
+  rpc ListAssets(ListAssetsRequest) returns (ListAssetsResponse) {
+    option (google.api.http) = {
+      get: "/v1beta1/{parent=organizations/*}/assets"
+    };
+  }
+
+  // Lists an organization or source's findings.
+  //
+  // To list across all sources provide a `-` as the source id.
+  // Example: /v1beta1/organizations/123/sources/-/findings
+  rpc ListFindings(ListFindingsRequest) returns (ListFindingsResponse) {
+    option (google.api.http) = {
+      get: "/v1beta1/{parent=organizations/*/sources/*}/findings"
+    };
+  }
+
+  // Lists all sources belonging to an organization.
+  rpc ListSources(ListSourcesRequest) returns (ListSourcesResponse) {
+    option (google.api.http) = {
+      get: "/v1beta1/{parent=organizations/*}/sources"
+    };
+  }
+
+  // Runs asset discovery. The discovery is tracked with a long-running
+  // operation.
+  //
+  // This API can only be called with limited frequency for an organization. If
+  // it is called too frequently the caller will receive a TOO_MANY_REQUESTS
+  // error.
+  rpc RunAssetDiscovery(RunAssetDiscoveryRequest)
+      returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1beta1/{parent=organizations/*}/assets:runDiscovery"
+      body: "*"
+    };
+  }
+
+  // Updates the state of a finding.
+  rpc SetFindingState(SetFindingStateRequest) returns (Finding) {
+    option (google.api.http) = {
+      post: "/v1beta1/{name=organizations/*/sources/*/findings/*}:setState"
+      body: "*"
+    };
+  }
+
+  // Sets the access control policy on the specified Source.
+  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest)
+      returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1beta1/{resource=organizations/*/sources/*}:setIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Returns the permissions that a caller has on the specified source.
+  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest)
+      returns (google.iam.v1.TestIamPermissionsResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/{resource=organizations/*/sources/*}:testIamPermissions"
+      body: "*"
+    };
+  }
+
+  // Creates or updates a finding. The corresponding source must exist for a
+  // finding creation to succeed.
+  rpc UpdateFinding(UpdateFindingRequest) returns (Finding) {
+    option (google.api.http) = {
+      patch: "/v1beta1/{finding.name=organizations/*/sources/*/findings/*}"
+      body: "finding"
+    };
+  }
+
+  // Updates an organization's settings.
+  rpc UpdateOrganizationSettings(UpdateOrganizationSettingsRequest)
+      returns (OrganizationSettings) {
+    option (google.api.http) = {
+      patch: "/v1beta1/{organization_settings.name=organizations/*/organizationSettings}"
+      body: "organization_settings"
+    };
+  }
+
+  // Updates a source.
+  rpc UpdateSource(UpdateSourceRequest) returns (Source) {
+    option (google.api.http) = {
+      patch: "/v1beta1/{source.name=organizations/*/sources/*}"
+      body: "source"
+    };
+  }
+
+  // Updates security marks.
+  rpc UpdateSecurityMarks(UpdateSecurityMarksRequest) returns (SecurityMarks) {
+    option (google.api.http) = {
+      patch: "/v1beta1/{security_marks.name=organizations/*/assets/*/securityMarks}"
+      body: "security_marks"
+      additional_bindings {
+        patch: "/v1beta1/{security_marks.name=organizations/*/sources/*/findings/*/securityMarks}"
+        body: "security_marks"
+      }
+    };
+  }
+}
+
+// Request message for creating a finding.
+message CreateFindingRequest {
+  // Resource name of the new finding's parent. Its format should be
+  // "organizations/[organization_id]/sources/[source_id]".
+  string parent = 1;
+
+  // Unique identifier provided by the client within the parent scope.
+  // It must be alphanumeric and less than or equal to 32 characters and
+  // greater than 0 characters in length.
+  string finding_id = 2;
+
+  // The Finding being created. The name and security_marks will be ignored as
+  // they are both output only fields on this resource.
+  Finding finding = 3;
+}
+
+// Request message for creating a source.
+message CreateSourceRequest {
+  // Resource name of the new source's parent. Its format should be
+  // "organizations/[organization_id]".
+  string parent = 1;
+
+  // The Source being created, only the display_name and description will be
+  // used. All other fields will be ignored.
+  Source source = 2;
+}
+
+// Request message for getting organization settings.
+message GetOrganizationSettingsRequest {
+  // Name of the organization to get organization settings for. Its format is
+  // "organizations/[organization_id]/organizationSettings".
+  string name = 1;
+}
+
+// Request message for getting a source.
+message GetSourceRequest {
+  // Relative resource name of the source. Its format is
+  // "organizations/[organization_id]/source/[source_id]".
+  string name = 1;
+}
+
+// Request message for grouping by assets.
+message GroupAssetsRequest {
+  // Name of the organization to groupBy. Its format is
+  // "organizations/[organization_id]".
+  string parent = 1;
+
+  // Expression that defines the filter to apply across assets.
+  // The expression is a list of zero or more restrictions combined via logical
+  // operators `AND` and `OR`.
+  // Parentheses are not supported, and `OR` has higher precedence than `AND`.
+  //
+  // Restrictions have the form `<field> <operator> <value>` and may have a `-`
+  // character in front of them to indicate negation. The fields map to those
+  // defined in the Asset resource. Examples include:
+  //
+  // * name
+  // * security_center_properties.resource_name
+  // * resource_properties.a_property
+  // * security_marks.marks.marka
+  //
+  // The supported operators are:
+  //
+  // * `=` for all value types.
+  // * `>`, `<`, `>=`, `<=` for integer values.
+  // * `:`, meaning substring matching, for strings.
+  //
+  // The supported value types are:
+  //
+  // * string literals in quotes.
+  // * integer literals without quotes.
+  // * boolean literals `true` and `false` without quotes.
+  //
+  // For example, `resource_properties.size = 100` is a valid filter string.
+  string filter = 2;
+
+  // Expression that defines what assets fields to use for grouping. The string
+  // value should follow SQL syntax: comma separated list of fields. For
+  // example:
+  // "security_center_properties.resource_project,security_center_properties.project".
+  //
+  // The following fields are supported when compare_duration is not set:
+  //
+  // * security_center_properties.resource_project
+  // * security_center_properties.resource_type
+  // * security_center_properties.resource_parent
+  //
+  // The following fields are supported when compare_duration is set:
+  //
+  // * security_center_properties.resource_type
+  string group_by = 3;
+
+  // When compare_duration is set, the Asset's "state" property is updated to
+  // indicate whether the asset was added, removed, or remained present during
+  // the compare_duration period of time that precedes the read_time. This is
+  // the time between (read_time - compare_duration) and read_time.
+  //
+  // The state value is derived based on the presence of the asset at the two
+  // points in time. Intermediate state changes between the two times don't
+  // affect the result. For example, the results aren't affected if the asset is
+  // removed and re-created again.
+  //
+  // Possible "state" values when compare_duration is specified:
+  //
+  // * "ADDED": indicates that the asset was not present before
+  //              compare_duration, but present at reference_time.
+  // * "REMOVED": indicates that the asset was present at the start of
+  //              compare_duration, but not present at reference_time.
+  // * "ACTIVE": indicates that the asset was present at both the
+  //              start and the end of the time period defined by
+  //              compare_duration and reference_time.
+  //
+  // This field is ignored if `state` is not a field in `group_by`.
+  google.protobuf.Duration compare_duration = 4;
+
+  // Time used as a reference point when filtering assets. The filter is limited
+  // to assets existing at the supplied time and their values are those at that
+  // specific time. Absence of this field will default to the API's version of
+  // NOW.
+  google.protobuf.Timestamp read_time = 5;
+
+  // The value returned by the last `GroupAssetsResponse`; indicates
+  // that this is a continuation of a prior `GroupAssets` call, and that the
+  // system should return the next page of data.
+  string page_token = 7;
+
+  // The maximum number of results to return in a single response. Default is
+  // 10, minimum is 1, maximum is 1000.
+  int32 page_size = 8;
+}
+
+// Response message for grouping by assets.
+message GroupAssetsResponse {
+  // Group results. There exists an element for each existing unique
+  // combination of property/values. The element contains a count for the number
+  // of times those specific property/values appear.
+  repeated GroupResult group_by_results = 1;
+
+  // Time used for executing the groupBy request.
+  google.protobuf.Timestamp read_time = 2;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results.
+  string next_page_token = 3;
+}
+
+// Request message for grouping by findings.
+message GroupFindingsRequest {
+  // Name of the source to groupBy. Its format is
+  // "organizations/[organization_id]/sources/[source_id]". To groupBy across
+  // all sources provide a source_id of `-`. For example:
+  // organizations/123/sources/-
+  string parent = 1;
+
+  // Expression that defines the filter to apply across findings.
+  // The expression is a list of one or more restrictions combined via logical
+  // operators `AND` and `OR`.
+  // Parentheses are not supported, and `OR` has higher precedence than `AND`.
+  //
+  // Restrictions have the form `<field> <operator> <value>` and may have a `-`
+  // character in front of them to indicate negation. Examples include:
+  //
+  //  * name
+  //  * source_properties.a_property
+  //  * security_marks.marks.marka
+  //
+  // The supported operators are:
+  //
+  // * `=` for all value types.
+  // * `>`, `<`, `>=`, `<=` for integer values.
+  // * `:`, meaning substring matching, for strings.
+  //
+  // The supported value types are:
+  //
+  // * string literals in quotes.
+  // * integer literals without quotes.
+  // * boolean literals `true` and `false` without quotes.
+  //
+  // For example, `source_properties.size = 100` is a valid filter string.
+  string filter = 2;
+
+  // Expression that defines what assets fields to use for grouping (including
+  // `state`). The string value should follow SQL syntax: comma separated list
+  // of fields. For example:
+  // "parent,resource_name".
+  //
+  // The following fields are supported:
+  //
+  // * resource_name
+  // * category
+  // * state
+  // * parent
+  string group_by = 3;
+
+  // Time used as a reference point when filtering findings. The filter is
+  // limited to findings existing at the supplied time and their values are
+  // those at that specific time. Absence of this field will default to the
+  // API's version of NOW.
+  google.protobuf.Timestamp read_time = 4;
+
+  // The value returned by the last `GroupFindingsResponse`; indicates
+  // that this is a continuation of a prior `GroupFindings` call, and
+  // that the system should return the next page of data.
+  string page_token = 5;
+
+  // The maximum number of results to return in a single response. Default is
+  // 10, minimum is 1, maximum is 1000.
+  int32 page_size = 6;
+}
+
+// Response message for group by findings.
+message GroupFindingsResponse {
+  // Group results. There exists an element for each existing unique
+  // combination of property/values. The element contains a count for the number
+  // of times those specific property/values appear.
+  repeated GroupResult group_by_results = 1;
+
+  // Time used for executing the groupBy request.
+  google.protobuf.Timestamp read_time = 2;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results.
+  string next_page_token = 3;
+}
+
+// Result containing the properties and count of a groupBy request.
+message GroupResult {
+  // Properties matching the groupBy fields in the request.
+  map<string, google.protobuf.Value> properties = 1;
+
+  // Total count of resources for the given properties.
+  int64 count = 2;
+}
+
+// Request message for listing sources.
+message ListSourcesRequest {
+  // Resource name of the parent of sources to list. Its format should be
+  // "organizations/[organization_id]".
+  string parent = 1;
+
+  // The value returned by the last `ListSourcesResponse`; indicates
+  // that this is a continuation of a prior `ListSources` call, and
+  // that the system should return the next page of data.
+  string page_token = 2;
+
+  // The maximum number of results to return in a single response. Default is
+  // 10, minimum is 1, maximum is 1000.
+  int32 page_size = 7;
+}
+
+// Response message for listing sources.
+message ListSourcesResponse {
+  // Sources belonging to the requested parent.
+  repeated Source sources = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results.
+  string next_page_token = 2;
+}
+
+// Request message for listing assets.
+message ListAssetsRequest {
+  // Name of the organization assets should belong to. Its format is
+  // "organizations/[organization_id]".
+  string parent = 1;
+
+  // Expression that defines the filter to apply across assets.
+  // The expression is a list of zero or more restrictions combined via logical
+  // operators `AND` and `OR`.
+  // Parentheses are not supported, and `OR` has higher precedence than `AND`.
+  //
+  // Restrictions have the form `<field> <operator> <value>` and may have a `-`
+  // character in front of them to indicate negation. The fields map to those
+  // defined in the Asset resource. Examples include:
+  //
+  // * name
+  // * security_center_properties.resource_name
+  // * resource_properties.a_property
+  // * security_marks.marks.marka
+  //
+  // The supported operators are:
+  //
+  // * `=` for all value types.
+  // * `>`, `<`, `>=`, `<=` for integer values.
+  // * `:`, meaning substring matching, for strings.
+  //
+  // The supported value types are:
+  //
+  // * string literals in quotes.
+  // * integer literals without quotes.
+  // * boolean literals `true` and `false` without quotes.
+  //
+  // For example, `resource_properties.size = 100` is a valid filter string.
+  string filter = 2;
+
+  // Expression that defines what fields and order to use for sorting. The
+  // string value should follow SQL syntax: comma separated list of fields. For
+  // example: "name,resource_properties.a_property". The default sorting order
+  // is ascending. To specify descending order for a field, a suffix " desc"
+  // should be appended to the field name. For example: "name
+  // desc,resource_properties.a_property". Redundant space characters in the
+  // syntax are insignificant. "name desc,resource_properties.a_property" and "
+  // name     desc  ,   resource_properties.a_property  " are equivalent.
+  string order_by = 3;
+
+  // Time used as a reference point when filtering assets. The filter is limited
+  // to assets existing at the supplied time and their values are those at that
+  // specific time. Absence of this field will default to the API's version of
+  // NOW.
+  google.protobuf.Timestamp read_time = 4;
+
+  // When compare_duration is set, the ListAssetResult's "state" attribute is
+  // updated to indicate whether the asset was added, removed, or remained
+  // present during the compare_duration period of time that precedes the
+  // read_time. This is the time between (read_time -
+  // compare_duration) and read_time.
+  //
+  // The state value is derived based on the presence of the asset at the two
+  // points in time. Intermediate state changes between the two times don't
+  // affect the result. For example, the results aren't affected if the asset is
+  // removed and re-created again.
+  //
+  // Possible "state" values when compare_duration is specified:
+  //
+  // * "ADDED": indicates that the asset was not present before
+  //              compare_duration, but present at read_time.
+  // * "REMOVED": indicates that the asset was present at the start of
+  //              compare_duration, but not present at read_time.
+  // * "ACTIVE": indicates that the asset was present at both the
+  //              start and the end of the time period defined by
+  //              compare_duration and read_time.
+  //
+  // If compare_duration is not specified, then the only possible state is
+  // "UNUSED", which indicates that the asset is present at read_time.
+  google.protobuf.Duration compare_duration = 5;
+
+  // Optional.
+  //
+  // A field mask to specify the ListAssetsResult fields to be listed in the
+  // response.
+  // An empty field mask will list all fields.
+  google.protobuf.FieldMask field_mask = 7;
+
+  // The value returned by the last `ListAssetsResponse`; indicates
+  // that this is a continuation of a prior `ListAssets` call, and
+  // that the system should return the next page of data.
+  string page_token = 8;
+
+  // The maximum number of results to return in a single response. Default is
+  // 10, minimum is 1, maximum is 1000.
+  int32 page_size = 9;
+}
+
+// Response message for listing assets.
+message ListAssetsResponse {
+  // Result containing the Asset and its State.
+  message ListAssetsResult {
+    // State of the asset.
+    //
+    // When querying across two points in time this describes
+    // the change between the two points: ADDED, REMOVED, or ACTIVE.
+    // If there was no compare_duration supplied in the request the state should
+    // be: UNUSED
+    enum State {
+      // Unspecified state.
+      STATE_UNSPECIFIED = 0;
+
+      // Request did not specify use of this field in the result.
+      UNUSED = 1;
+
+      // Asset was added between the points in time.
+      ADDED = 2;
+
+      // Asset was removed between the points in time.
+      REMOVED = 3;
+
+      // Asset was active at both point(s) in time.
+      ACTIVE = 4;
+    }
+
+    // Asset matching the search request.
+    Asset asset = 1;
+
+    // State of the asset.
+    State state = 2;
+  }
+
+  // Assets matching the list request.
+  repeated ListAssetsResult list_assets_results = 1;
+
+  // Time used for executing the list request.
+  google.protobuf.Timestamp read_time = 2;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results.
+  string next_page_token = 3;
+
+  // The total number of assets matching the query.
+  int32 total_size = 4;
+}
+
+// Request message for listing findings.
+message ListFindingsRequest {
+  // Name of the source the findings belong to. Its format is
+  // "organizations/[organization_id]/sources/[source_id]". To list across all
+  // sources provide a source_id of `-`. For example:
+  // organizations/123/sources/-
+  string parent = 1;
+
+  // Expression that defines the filter to apply across findings.
+  // The expression is a list of one or more restrictions combined via logical
+  // operators `AND` and `OR`.
+  // Parentheses are not supported, and `OR` has higher precedence than `AND`.
+  //
+  // Restrictions have the form `<field> <operator> <value>` and may have a `-`
+  // character in front of them to indicate negation. Examples include:
+  //
+  //  * name
+  //  * source_properties.a_property
+  //  * security_marks.marks.marka
+  //
+  // The supported operators are:
+  //
+  // * `=` for all value types.
+  // * `>`, `<`, `>=`, `<=` for integer values.
+  // * `:`, meaning substring matching, for strings.
+  //
+  // The supported value types are:
+  //
+  // * string literals in quotes.
+  // * integer literals without quotes.
+  // * boolean literals `true` and `false` without quotes.
+  //
+  // For example, `source_properties.size = 100` is a valid filter string.
+  string filter = 2;
+
+  // Expression that defines what fields and order to use for sorting. The
+  // string value should follow SQL syntax: comma separated list of fields. For
+  // example: "name,resource_properties.a_property". The default sorting order
+  // is ascending. To specify descending order for a field, a suffix " desc"
+  // should be appended to the field name. For example: "name
+  // desc,source_properties.a_property". Redundant space characters in the
+  // syntax are insignificant. "name desc,source_properties.a_property" and "
+  // name     desc  ,   source_properties.a_property  " are equivalent.
+  string order_by = 3;
+
+  // Time used as a reference point when filtering findings. The filter is
+  // limited to findings existing at the supplied time and their values are
+  // those at that specific time. Absence of this field will default to the
+  // API's version of NOW.
+  google.protobuf.Timestamp read_time = 4;
+
+  // Optional.
+  //
+  // A field mask to specify the Finding fields to be listed in the response.
+  // An empty field mask will list all fields.
+  google.protobuf.FieldMask field_mask = 5;
+
+  // The value returned by the last `ListFindingsResponse`; indicates
+  // that this is a continuation of a prior `ListFindings` call, and
+  // that the system should return the next page of data.
+  string page_token = 6;
+
+  // The maximum number of results to return in a single response. Default is
+  // 10, minimum is 1, maximum is 1000.
+  int32 page_size = 7;
+}
+
+// Response message for listing findings.
+message ListFindingsResponse {
+  // Findings matching the list request.
+  repeated Finding findings = 1;
+
+  // Time used for executing the list request.
+  google.protobuf.Timestamp read_time = 2;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results.
+  string next_page_token = 3;
+
+  // The total number of findings matching the query.
+  int32 total_size = 4;
+}
+
+// Request message for updating a finding's state.
+message SetFindingStateRequest {
+  // The relative resource name of the finding. See:
+  // https://cloud.google.com/apis/design/resource_names#relative_resource_name
+  // Example:
+  // "organizations/123/sources/456/finding/789".
+  string name = 1;
+
+  // The desired State of the finding.
+  Finding.State state = 2;
+
+  // The time at which the updated state takes effect.
+  google.protobuf.Timestamp start_time = 3;
+}
+
+// Request message for running asset discovery for an organization.
+message RunAssetDiscoveryRequest {
+  // Name of the organization to run asset discovery for. Its format is
+  // "organizations/[organization_id]".
+  string parent = 1;
+}
+
+// Request message for updating or creating a finding.
+message UpdateFindingRequest {
+  // The finding resource to update or create if it does not already exist.
+  // parent, security_marks, and update_time will be ignored.
+  //
+  // In the case of creation, the finding id portion of the name must
+  // alphanumeric and less than or equal to 32 characters and greater than 0
+  // characters in length.
+  Finding finding = 1;
+
+  // The FieldMask to use when updating the finding resource. This field should
+  // not be specified when creating a finding.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for updating an organization's settings.
+message UpdateOrganizationSettingsRequest {
+  // The organization settings resource to update.
+  OrganizationSettings organization_settings = 1;
+
+  // The FieldMask to use when updating the settings resource.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for updating a source.
+message UpdateSourceRequest {
+  // The source resource to update.
+  Source source = 1;
+
+  // The FieldMask to use when updating the source resource.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for updating a SecurityMarks resource.
+message UpdateSecurityMarksRequest {
+  // The security marks resource to update.
+  SecurityMarks security_marks = 1;
+
+  // The FieldMask to use when updating the security marks resource.
+  google.protobuf.FieldMask update_mask = 2;
+
+  // The time at which the updated SecurityMarks take effect.
+  google.protobuf.Timestamp start_time = 3;
+}
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/securitycenter_service_pb2.py b/securitycenter/google/cloud/securitycenter_v1beta1/proto/securitycenter_service_pb2.py
index 42d309b63cdb..a19b846dcddc 100644
--- a/securitycenter/google/cloud/securitycenter_v1beta1/proto/securitycenter_service_pb2.py
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/securitycenter_service_pb2.py
@@ -2972,3 +2972,4 @@
 DESCRIPTOR.services_by_name["SecurityCenter"] = _SECURITYCENTER
 
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/source.proto b/securitycenter/google/cloud/securitycenter_v1beta1/proto/source.proto
new file mode 100644
index 000000000000..cc1fae6eaa66
--- /dev/null
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/source.proto
@@ -0,0 +1,53 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.securitycenter.v1beta1;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/securitycenter/v1beta1;securitycenter";
+option java_multiple_files = true;
+option java_package = "com.google.cloud.securitycenter.v1beta1";
+
+// Cloud Security Command Center's (Cloud SCC) finding source. A finding source
+// is an entity or a mechanism that can produce a finding. A source is like a
+// container of findings that come from the same scanner, logger, monitor, etc.
+message Source {
+  // The relative resource name of this source. See:
+  // https://cloud.google.com/apis/design/resource_names#relative_resource_name
+  // Example:
+  // "organizations/123/sources/456"
+  string name = 1;
+
+  // The source's display name.
+  // A source's display name must be unique amongst its siblings, for example,
+  // two sources with the same parent can't share the same display name.
+  // The display name must start and end with a letter or digit, may contain
+  // letters, digits, spaces, hyphens, and underscores, and can be no longer
+  // than 32 characters. This is captured by the regular expression:
+  // [\p{L}\p{N}]({\p{L}\p{N}_- ]{0,30}[\p{L}\p{N}])?.
+  string display_name = 2;
+
+  // The description of the source (max of 1024 characters).
+  // Example:
+  // "Cloud Security Scanner is a web security scanner for common
+  // vulnerabilities in App Engine applications. It can automatically
+  // scan and detect four common vulnerabilities, including cross-site-scripting
+  // (XSS), Flash injection, mixed content (HTTP in HTTPS), and
+  // outdated/insecure libraries."
+  string description = 3;
+}
diff --git a/securitycenter/google/cloud/securitycenter_v1beta1/proto/source_pb2.py b/securitycenter/google/cloud/securitycenter_v1beta1/proto/source_pb2.py
index 0fa2b9c2771d..0f2aa9806de1 100644
--- a/securitycenter/google/cloud/securitycenter_v1beta1/proto/source_pb2.py
+++ b/securitycenter/google/cloud/securitycenter_v1beta1/proto/source_pb2.py
@@ -151,3 +151,4 @@
 
 DESCRIPTOR._options = None
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/securitycenter/synth.metadata b/securitycenter/synth.metadata
index a24e49204a2c..8b1afbccccde 100644
--- a/securitycenter/synth.metadata
+++ b/securitycenter/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:26:19.304173Z",
+  "updateTime": "2019-01-24T17:26:45.120902Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/securitycenter/synth.py b/securitycenter/synth.py
index 4f1d60325ce4..1cc37cd3c887 100644
--- a/securitycenter/synth.py
+++ b/securitycenter/synth.py
@@ -22,7 +22,7 @@
 # ----------------------------------------------------------------------------
 # Generate securitycenter GAPIC layer
 # ----------------------------------------------------------------------------
-library = gapic.py_library("securitycenter", "v1beta1")
+library = gapic.py_library("securitycenter", "v1beta1", include_protos=True,)
 
 s.move(
     library,
diff --git a/spanner/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin.proto b/spanner/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin.proto
new file mode 100644
index 000000000000..56dbff19e17b
--- /dev/null
+++ b/spanner/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin.proto
@@ -0,0 +1,302 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.admin.database.v1;
+
+import "google/api/annotations.proto";
+import "google/iam/v1/iam_policy.proto";
+import "google/iam/v1/policy.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Spanner.Admin.Database.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/admin/database/v1;database";
+option java_multiple_files = true;
+option java_outer_classname = "SpannerDatabaseAdminProto";
+option java_package = "com.google.spanner.admin.database.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\Admin\\Database\\V1";
+
+
+// Cloud Spanner Database Admin API
+//
+// The Cloud Spanner Database Admin API can be used to create, drop, and
+// list databases. It also enables updating the schema of pre-existing
+// databases.
+service DatabaseAdmin {
+  // Lists Cloud Spanner databases.
+  rpc ListDatabases(ListDatabasesRequest) returns (ListDatabasesResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/instances/*}/databases"
+    };
+  }
+
+  // Creates a new Cloud Spanner database and starts to prepare it for serving.
+  // The returned [long-running operation][google.longrunning.Operation] will
+  // have a name of the format `<database_name>/operations/<operation_id>` and
+  // can be used to track preparation of the database. The
+  // [metadata][google.longrunning.Operation.metadata] field type is
+  // [CreateDatabaseMetadata][google.spanner.admin.database.v1.CreateDatabaseMetadata]. The
+  // [response][google.longrunning.Operation.response] field type is
+  // [Database][google.spanner.admin.database.v1.Database], if successful.
+  rpc CreateDatabase(CreateDatabaseRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/instances/*}/databases"
+      body: "*"
+    };
+  }
+
+  // Gets the state of a Cloud Spanner database.
+  rpc GetDatabase(GetDatabaseRequest) returns (Database) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/instances/*/databases/*}"
+    };
+  }
+
+  // Updates the schema of a Cloud Spanner database by
+  // creating/altering/dropping tables, columns, indexes, etc. The returned
+  // [long-running operation][google.longrunning.Operation] will have a name of
+  // the format `<database_name>/operations/<operation_id>` and can be used to
+  // track execution of the schema change(s). The
+  // [metadata][google.longrunning.Operation.metadata] field type is
+  // [UpdateDatabaseDdlMetadata][google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata].  The operation has no response.
+  rpc UpdateDatabaseDdl(UpdateDatabaseDdlRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v1/{database=projects/*/instances/*/databases/*}/ddl"
+      body: "*"
+    };
+  }
+
+  // Drops (aka deletes) a Cloud Spanner database.
+  rpc DropDatabase(DropDatabaseRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1/{database=projects/*/instances/*/databases/*}"
+    };
+  }
+
+  // Returns the schema of a Cloud Spanner database as a list of formatted
+  // DDL statements. This method does not show pending schema updates, those may
+  // be queried using the [Operations][google.longrunning.Operations] API.
+  rpc GetDatabaseDdl(GetDatabaseDdlRequest) returns (GetDatabaseDdlResponse) {
+    option (google.api.http) = {
+      get: "/v1/{database=projects/*/instances/*/databases/*}/ddl"
+    };
+  }
+
+  // Sets the access control policy on a database resource. Replaces any
+  // existing policy.
+  //
+  // Authorization requires `spanner.databases.setIamPolicy` permission on
+  // [resource][google.iam.v1.SetIamPolicyRequest.resource].
+  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*/databases/*}:setIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Gets the access control policy for a database resource. Returns an empty
+  // policy if a database exists but does not have a policy set.
+  //
+  // Authorization requires `spanner.databases.getIamPolicy` permission on
+  // [resource][google.iam.v1.GetIamPolicyRequest.resource].
+  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*/databases/*}:getIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Returns permissions that the caller has on the specified database resource.
+  //
+  // Attempting this RPC on a non-existent Cloud Spanner database will result in
+  // a NOT_FOUND error if the user has `spanner.databases.list` permission on
+  // the containing Cloud Spanner instance. Otherwise returns an empty set of
+  // permissions.
+  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*/databases/*}:testIamPermissions"
+      body: "*"
+    };
+  }
+}
+
+// A Cloud Spanner database.
+message Database {
+  // Indicates the current state of the database.
+  enum State {
+    // Not specified.
+    STATE_UNSPECIFIED = 0;
+
+    // The database is still being created. Operations on the database may fail
+    // with `FAILED_PRECONDITION` in this state.
+    CREATING = 1;
+
+    // The database is fully created and ready for use.
+    READY = 2;
+  }
+
+  // Required. The name of the database. Values are of the form
+  // `projects/<project>/instances/<instance>/databases/<database>`,
+  // where `<database>` is as specified in the `CREATE DATABASE`
+  // statement. This name can be passed to other API methods to
+  // identify the database.
+  string name = 1;
+
+  // Output only. The current database state.
+  State state = 2;
+}
+
+// The request for [ListDatabases][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases].
+message ListDatabasesRequest {
+  // Required. The instance whose databases should be listed.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // Number of databases to be returned in the response. If 0 or less,
+  // defaults to the server's maximum allowed page size.
+  int32 page_size = 3;
+
+  // If non-empty, `page_token` should contain a
+  // [next_page_token][google.spanner.admin.database.v1.ListDatabasesResponse.next_page_token] from a
+  // previous [ListDatabasesResponse][google.spanner.admin.database.v1.ListDatabasesResponse].
+  string page_token = 4;
+}
+
+// The response for [ListDatabases][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases].
+message ListDatabasesResponse {
+  // Databases that matched the request.
+  repeated Database databases = 1;
+
+  // `next_page_token` can be sent in a subsequent
+  // [ListDatabases][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases] call to fetch more
+  // of the matching databases.
+  string next_page_token = 2;
+}
+
+// The request for [CreateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.CreateDatabase].
+message CreateDatabaseRequest {
+  // Required. The name of the instance that will serve the new database.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // Required. A `CREATE DATABASE` statement, which specifies the ID of the
+  // new database.  The database ID must conform to the regular expression
+  // `[a-z][a-z0-9_\-]*[a-z0-9]` and be between 2 and 30 characters in length.
+  // If the database ID is a reserved word or if it contains a hyphen, the
+  // database ID must be enclosed in backticks (`` ` ``).
+  string create_statement = 2;
+
+  // An optional list of DDL statements to run inside the newly created
+  // database. Statements can create tables, indexes, etc. These
+  // statements execute atomically with the creation of the database:
+  // if there is an error in any statement, the database is not created.
+  repeated string extra_statements = 3;
+}
+
+// Metadata type for the operation returned by
+// [CreateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.CreateDatabase].
+message CreateDatabaseMetadata {
+  // The database being created.
+  string database = 1;
+}
+
+// The request for [GetDatabase][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabase].
+message GetDatabaseRequest {
+  // Required. The name of the requested database. Values are of the form
+  // `projects/<project>/instances/<instance>/databases/<database>`.
+  string name = 1;
+}
+
+// Enqueues the given DDL statements to be applied, in order but not
+// necessarily all at once, to the database schema at some point (or
+// points) in the future. The server checks that the statements
+// are executable (syntactically valid, name tables that exist, etc.)
+// before enqueueing them, but they may still fail upon
+// later execution (e.g., if a statement from another batch of
+// statements is applied first and it conflicts in some way, or if
+// there is some data-related problem like a `NULL` value in a column to
+// which `NOT NULL` would be added). If a statement fails, all
+// subsequent statements in the batch are automatically cancelled.
+//
+// Each batch of statements is assigned a name which can be used with
+// the [Operations][google.longrunning.Operations] API to monitor
+// progress. See the
+// [operation_id][google.spanner.admin.database.v1.UpdateDatabaseDdlRequest.operation_id] field for more
+// details.
+message UpdateDatabaseDdlRequest {
+  // Required. The database to update.
+  string database = 1;
+
+  // DDL statements to be applied to the database.
+  repeated string statements = 2;
+
+  // If empty, the new update request is assigned an
+  // automatically-generated operation ID. Otherwise, `operation_id`
+  // is used to construct the name of the resulting
+  // [Operation][google.longrunning.Operation].
+  //
+  // Specifying an explicit operation ID simplifies determining
+  // whether the statements were executed in the event that the
+  // [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl] call is replayed,
+  // or the return value is otherwise lost: the [database][google.spanner.admin.database.v1.UpdateDatabaseDdlRequest.database] and
+  // `operation_id` fields can be combined to form the
+  // [name][google.longrunning.Operation.name] of the resulting
+  // [longrunning.Operation][google.longrunning.Operation]: `<database>/operations/<operation_id>`.
+  //
+  // `operation_id` should be unique within the database, and must be
+  // a valid identifier: `[a-z][a-z0-9_]*`. Note that
+  // automatically-generated operation IDs always begin with an
+  // underscore. If the named operation already exists,
+  // [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl] returns
+  // `ALREADY_EXISTS`.
+  string operation_id = 3;
+}
+
+// Metadata type for the operation returned by
+// [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl].
+message UpdateDatabaseDdlMetadata {
+  // The database being modified.
+  string database = 1;
+
+  // For an update this list contains all the statements. For an
+  // individual statement, this list contains only that statement.
+  repeated string statements = 2;
+
+  // Reports the commit timestamps of all statements that have
+  // succeeded so far, where `commit_timestamps[i]` is the commit
+  // timestamp for the statement `statements[i]`.
+  repeated google.protobuf.Timestamp commit_timestamps = 3;
+}
+
+// The request for [DropDatabase][google.spanner.admin.database.v1.DatabaseAdmin.DropDatabase].
+message DropDatabaseRequest {
+  // Required. The database to be dropped.
+  string database = 1;
+}
+
+// The request for [GetDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabaseDdl].
+message GetDatabaseDdlRequest {
+  // Required. The database whose schema we wish to get.
+  string database = 1;
+}
+
+// The response for [GetDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabaseDdl].
+message GetDatabaseDdlResponse {
+  // A list of formatted DDL statements defining the schema of the database
+  // specified in the request.
+  repeated string statements = 1;
+}
diff --git a/spanner/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin.proto b/spanner/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin.proto
new file mode 100644
index 000000000000..e960e5428e3a
--- /dev/null
+++ b/spanner/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin.proto
@@ -0,0 +1,475 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.admin.instance.v1;
+
+import "google/api/annotations.proto";
+import "google/iam/v1/iam_policy.proto";
+import "google/iam/v1/policy.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Spanner.Admin.Instance.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/admin/instance/v1;instance";
+option java_multiple_files = true;
+option java_outer_classname = "SpannerInstanceAdminProto";
+option java_package = "com.google.spanner.admin.instance.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\Admin\\Instance\\V1";
+
+
+// Cloud Spanner Instance Admin API
+//
+// The Cloud Spanner Instance Admin API can be used to create, delete,
+// modify and list instances. Instances are dedicated Cloud Spanner serving
+// and storage resources to be used by Cloud Spanner databases.
+//
+// Each instance has a "configuration", which dictates where the
+// serving resources for the Cloud Spanner instance are located (e.g.,
+// US-central, Europe). Configurations are created by Google based on
+// resource availability.
+//
+// Cloud Spanner billing is based on the instances that exist and their
+// sizes. After an instance exists, there are no additional
+// per-database or per-operation charges for use of the instance
+// (though there may be additional network bandwidth charges).
+// Instances offer isolation: problems with databases in one instance
+// will not affect other instances. However, within an instance
+// databases can affect each other. For example, if one database in an
+// instance receives a lot of requests and consumes most of the
+// instance resources, fewer resources are available for other
+// databases in that instance, and their performance may suffer.
+service InstanceAdmin {
+  // Lists the supported instance configurations for a given project.
+  rpc ListInstanceConfigs(ListInstanceConfigsRequest) returns (ListInstanceConfigsResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*}/instanceConfigs"
+    };
+  }
+
+  // Gets information about a particular instance configuration.
+  rpc GetInstanceConfig(GetInstanceConfigRequest) returns (InstanceConfig) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/instanceConfigs/*}"
+    };
+  }
+
+  // Lists all instances in the given project.
+  rpc ListInstances(ListInstancesRequest) returns (ListInstancesResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*}/instances"
+    };
+  }
+
+  // Gets information about a particular instance.
+  rpc GetInstance(GetInstanceRequest) returns (Instance) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/instances/*}"
+    };
+  }
+
+  // Creates an instance and begins preparing it to begin serving. The
+  // returned [long-running operation][google.longrunning.Operation]
+  // can be used to track the progress of preparing the new
+  // instance. The instance name is assigned by the caller. If the
+  // named instance already exists, `CreateInstance` returns
+  // `ALREADY_EXISTS`.
+  //
+  // Immediately upon completion of this request:
+  //
+  //   * The instance is readable via the API, with all requested attributes
+  //     but no allocated resources. Its state is `CREATING`.
+  //
+  // Until completion of the returned operation:
+  //
+  //   * Cancelling the operation renders the instance immediately unreadable
+  //     via the API.
+  //   * The instance can be deleted.
+  //   * All other attempts to modify the instance are rejected.
+  //
+  // Upon completion of the returned operation:
+  //
+  //   * Billing for all successfully-allocated resources begins (some types
+  //     may have lower than the requested levels).
+  //   * Databases can be created in the instance.
+  //   * The instance's allocated resource levels are readable via the API.
+  //   * The instance's state becomes `READY`.
+  //
+  // The returned [long-running operation][google.longrunning.Operation] will
+  // have a name of the format `<instance_name>/operations/<operation_id>` and
+  // can be used to track creation of the instance.  The
+  // [metadata][google.longrunning.Operation.metadata] field type is
+  // [CreateInstanceMetadata][google.spanner.admin.instance.v1.CreateInstanceMetadata].
+  // The [response][google.longrunning.Operation.response] field type is
+  // [Instance][google.spanner.admin.instance.v1.Instance], if successful.
+  rpc CreateInstance(CreateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*}/instances"
+      body: "*"
+    };
+  }
+
+  // Updates an instance, and begins allocating or releasing resources
+  // as requested. The returned [long-running
+  // operation][google.longrunning.Operation] can be used to track the
+  // progress of updating the instance. If the named instance does not
+  // exist, returns `NOT_FOUND`.
+  //
+  // Immediately upon completion of this request:
+  //
+  //   * For resource types for which a decrease in the instance's allocation
+  //     has been requested, billing is based on the newly-requested level.
+  //
+  // Until completion of the returned operation:
+  //
+  //   * Cancelling the operation sets its metadata's
+  //     [cancel_time][google.spanner.admin.instance.v1.UpdateInstanceMetadata.cancel_time], and begins
+  //     restoring resources to their pre-request values. The operation
+  //     is guaranteed to succeed at undoing all resource changes,
+  //     after which point it terminates with a `CANCELLED` status.
+  //   * All other attempts to modify the instance are rejected.
+  //   * Reading the instance via the API continues to give the pre-request
+  //     resource levels.
+  //
+  // Upon completion of the returned operation:
+  //
+  //   * Billing begins for all successfully-allocated resources (some types
+  //     may have lower than the requested levels).
+  //   * All newly-reserved resources are available for serving the instance's
+  //     tables.
+  //   * The instance's new resource levels are readable via the API.
+  //
+  // The returned [long-running operation][google.longrunning.Operation] will
+  // have a name of the format `<instance_name>/operations/<operation_id>` and
+  // can be used to track the instance modification.  The
+  // [metadata][google.longrunning.Operation.metadata] field type is
+  // [UpdateInstanceMetadata][google.spanner.admin.instance.v1.UpdateInstanceMetadata].
+  // The [response][google.longrunning.Operation.response] field type is
+  // [Instance][google.spanner.admin.instance.v1.Instance], if successful.
+  //
+  // Authorization requires `spanner.instances.update` permission on
+  // resource [name][google.spanner.admin.instance.v1.Instance.name].
+  rpc UpdateInstance(UpdateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v1/{instance.name=projects/*/instances/*}"
+      body: "*"
+    };
+  }
+
+  // Deletes an instance.
+  //
+  // Immediately upon completion of the request:
+  //
+  //   * Billing ceases for all of the instance's reserved resources.
+  //
+  // Soon afterward:
+  //
+  //   * The instance and *all of its databases* immediately and
+  //     irrevocably disappear from the API. All data in the databases
+  //     is permanently deleted.
+  rpc DeleteInstance(DeleteInstanceRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1/{name=projects/*/instances/*}"
+    };
+  }
+
+  // Sets the access control policy on an instance resource. Replaces any
+  // existing policy.
+  //
+  // Authorization requires `spanner.instances.setIamPolicy` on
+  // [resource][google.iam.v1.SetIamPolicyRequest.resource].
+  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*}:setIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Gets the access control policy for an instance resource. Returns an empty
+  // policy if an instance exists but does not have a policy set.
+  //
+  // Authorization requires `spanner.instances.getIamPolicy` on
+  // [resource][google.iam.v1.GetIamPolicyRequest.resource].
+  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*}:getIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Returns permissions that the caller has on the specified instance resource.
+  //
+  // Attempting this RPC on a non-existent Cloud Spanner instance resource will
+  // result in a NOT_FOUND error if the user has `spanner.instances.list`
+  // permission on the containing Google Cloud Project. Otherwise returns an
+  // empty set of permissions.
+  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*}:testIamPermissions"
+      body: "*"
+    };
+  }
+}
+
+// A possible configuration for a Cloud Spanner instance. Configurations
+// define the geographic placement of nodes and their replication.
+message InstanceConfig {
+  // A unique identifier for the instance configuration.  Values
+  // are of the form
+  // `projects/<project>/instanceConfigs/[a-z][-a-z0-9]*`
+  string name = 1;
+
+  // The name of this instance configuration as it appears in UIs.
+  string display_name = 2;
+}
+
+// An isolated set of Cloud Spanner resources on which databases can be hosted.
+message Instance {
+  // Indicates the current state of the instance.
+  enum State {
+    // Not specified.
+    STATE_UNSPECIFIED = 0;
+
+    // The instance is still being created. Resources may not be
+    // available yet, and operations such as database creation may not
+    // work.
+    CREATING = 1;
+
+    // The instance is fully created and ready to do work such as
+    // creating databases.
+    READY = 2;
+  }
+
+  // Required. A unique identifier for the instance, which cannot be changed
+  // after the instance is created. Values are of the form
+  // `projects/<project>/instances/[a-z][-a-z0-9]*[a-z0-9]`. The final
+  // segment of the name must be between 6 and 30 characters in length.
+  string name = 1;
+
+  // Required. The name of the instance's configuration. Values are of the form
+  // `projects/<project>/instanceConfigs/<configuration>`. See
+  // also [InstanceConfig][google.spanner.admin.instance.v1.InstanceConfig] and
+  // [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs].
+  string config = 2;
+
+  // Required. The descriptive name for this instance as it appears in UIs.
+  // Must be unique per project and between 4 and 30 characters in length.
+  string display_name = 3;
+
+  // Required. The number of nodes allocated to this instance. This may be zero
+  // in API responses for instances that are not yet in state `READY`.
+  //
+  // See [the documentation](https://cloud.google.com/spanner/docs/instances#node_count)
+  // for more information about nodes.
+  int32 node_count = 5;
+
+  // Output only. The current instance state. For
+  // [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance], the state must be
+  // either omitted or set to `CREATING`. For
+  // [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance], the state must be
+  // either omitted or set to `READY`.
+  State state = 6;
+
+  // Cloud Labels are a flexible and lightweight mechanism for organizing cloud
+  // resources into groups that reflect a customer's organizational needs and
+  // deployment strategies. Cloud Labels can be used to filter collections of
+  // resources. They can be used to control how resource metrics are aggregated.
+  // And they can be used as arguments to policy management rules (e.g. route,
+  // firewall, load balancing, etc.).
+  //
+  //  * Label keys must be between 1 and 63 characters long and must conform to
+  //    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+  //  * Label values must be between 0 and 63 characters long and must conform
+  //    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+  //  * No more than 64 labels can be associated with a given resource.
+  //
+  // See https://goo.gl/xmQnxf for more information on and examples of labels.
+  //
+  // If you plan to use labels in your own code, please note that additional
+  // characters may be allowed in the future. And so you are advised to use an
+  // internal label representation, such as JSON, which doesn't rely upon
+  // specific characters being disallowed.  For example, representing labels
+  // as the string:  name + "_" + value  would prove problematic if we were to
+  // allow "_" in a future release.
+  map<string, string> labels = 7;
+}
+
+// The request for [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs].
+message ListInstanceConfigsRequest {
+  // Required. The name of the project for which a list of supported instance
+  // configurations is requested. Values are of the form
+  // `projects/<project>`.
+  string parent = 1;
+
+  // Number of instance configurations to be returned in the response. If 0 or
+  // less, defaults to the server's maximum allowed page size.
+  int32 page_size = 2;
+
+  // If non-empty, `page_token` should contain a
+  // [next_page_token][google.spanner.admin.instance.v1.ListInstanceConfigsResponse.next_page_token]
+  // from a previous [ListInstanceConfigsResponse][google.spanner.admin.instance.v1.ListInstanceConfigsResponse].
+  string page_token = 3;
+}
+
+// The response for [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs].
+message ListInstanceConfigsResponse {
+  // The list of requested instance configurations.
+  repeated InstanceConfig instance_configs = 1;
+
+  // `next_page_token` can be sent in a subsequent
+  // [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs] call to
+  // fetch more of the matching instance configurations.
+  string next_page_token = 2;
+}
+
+// The request for
+// [GetInstanceConfigRequest][google.spanner.admin.instance.v1.InstanceAdmin.GetInstanceConfig].
+message GetInstanceConfigRequest {
+  // Required. The name of the requested instance configuration. Values are of
+  // the form `projects/<project>/instanceConfigs/<config>`.
+  string name = 1;
+}
+
+// The request for [GetInstance][google.spanner.admin.instance.v1.InstanceAdmin.GetInstance].
+message GetInstanceRequest {
+  // Required. The name of the requested instance. Values are of the form
+  // `projects/<project>/instances/<instance>`.
+  string name = 1;
+}
+
+// The request for [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance].
+message CreateInstanceRequest {
+  // Required. The name of the project in which to create the instance. Values
+  // are of the form `projects/<project>`.
+  string parent = 1;
+
+  // Required. The ID of the instance to create.  Valid identifiers are of the
+  // form `[a-z][-a-z0-9]*[a-z0-9]` and must be between 6 and 30 characters in
+  // length.
+  string instance_id = 2;
+
+  // Required. The instance to create.  The name may be omitted, but if
+  // specified must be `<parent>/instances/<instance_id>`.
+  Instance instance = 3;
+}
+
+// The request for [ListInstances][google.spanner.admin.instance.v1.InstanceAdmin.ListInstances].
+message ListInstancesRequest {
+  // Required. The name of the project for which a list of instances is
+  // requested. Values are of the form `projects/<project>`.
+  string parent = 1;
+
+  // Number of instances to be returned in the response. If 0 or less, defaults
+  // to the server's maximum allowed page size.
+  int32 page_size = 2;
+
+  // If non-empty, `page_token` should contain a
+  // [next_page_token][google.spanner.admin.instance.v1.ListInstancesResponse.next_page_token] from a
+  // previous [ListInstancesResponse][google.spanner.admin.instance.v1.ListInstancesResponse].
+  string page_token = 3;
+
+  // An expression for filtering the results of the request. Filter rules are
+  // case insensitive. The fields eligible for filtering are:
+  //
+  //   * `name`
+  //   * `display_name`
+  //   * `labels.key` where key is the name of a label
+  //
+  // Some examples of using filters are:
+  //
+  //   * `name:*` --> The instance has a name.
+  //   * `name:Howl` --> The instance's name contains the string "howl".
+  //   * `name:HOWL` --> Equivalent to above.
+  //   * `NAME:howl` --> Equivalent to above.
+  //   * `labels.env:*` --> The instance has the label "env".
+  //   * `labels.env:dev` --> The instance has the label "env" and the value of
+  //                        the label contains the string "dev".
+  //   * `name:howl labels.env:dev` --> The instance's name contains "howl" and
+  //                                  it has the label "env" with its value
+  //                                  containing "dev".
+  string filter = 4;
+}
+
+// The response for [ListInstances][google.spanner.admin.instance.v1.InstanceAdmin.ListInstances].
+message ListInstancesResponse {
+  // The list of requested instances.
+  repeated Instance instances = 1;
+
+  // `next_page_token` can be sent in a subsequent
+  // [ListInstances][google.spanner.admin.instance.v1.InstanceAdmin.ListInstances] call to fetch more
+  // of the matching instances.
+  string next_page_token = 2;
+}
+
+// The request for [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance].
+message UpdateInstanceRequest {
+  // Required. The instance to update, which must always include the instance
+  // name.  Otherwise, only fields mentioned in [][google.spanner.admin.instance.v1.UpdateInstanceRequest.field_mask] need be included.
+  Instance instance = 1;
+
+  // Required. A mask specifying which fields in [][google.spanner.admin.instance.v1.UpdateInstanceRequest.instance] should be updated.
+  // The field mask must always be specified; this prevents any future fields in
+  // [][google.spanner.admin.instance.v1.Instance] from being erased accidentally by clients that do not know
+  // about them.
+  google.protobuf.FieldMask field_mask = 2;
+}
+
+// The request for [DeleteInstance][google.spanner.admin.instance.v1.InstanceAdmin.DeleteInstance].
+message DeleteInstanceRequest {
+  // Required. The name of the instance to be deleted. Values are of the form
+  // `projects/<project>/instances/<instance>`
+  string name = 1;
+}
+
+// Metadata type for the operation returned by
+// [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance].
+message CreateInstanceMetadata {
+  // The instance being created.
+  Instance instance = 1;
+
+  // The time at which the
+  // [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance] request was
+  // received.
+  google.protobuf.Timestamp start_time = 2;
+
+  // The time at which this operation was cancelled. If set, this operation is
+  // in the process of undoing itself (which is guaranteed to succeed) and
+  // cannot be cancelled again.
+  google.protobuf.Timestamp cancel_time = 3;
+
+  // The time at which this operation failed or was completed successfully.
+  google.protobuf.Timestamp end_time = 4;
+}
+
+// Metadata type for the operation returned by
+// [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance].
+message UpdateInstanceMetadata {
+  // The desired end state of the update.
+  Instance instance = 1;
+
+  // The time at which [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance]
+  // request was received.
+  google.protobuf.Timestamp start_time = 2;
+
+  // The time at which this operation was cancelled. If set, this operation is
+  // in the process of undoing itself (which is guaranteed to succeed) and
+  // cannot be cancelled again.
+  google.protobuf.Timestamp cancel_time = 3;
+
+  // The time at which this operation failed or was completed successfully.
+  google.protobuf.Timestamp end_time = 4;
+}
diff --git a/spanner/google/cloud/spanner_v1/proto/keys.proto b/spanner/google/cloud/spanner_v1/proto/keys.proto
new file mode 100644
index 000000000000..2078610f310f
--- /dev/null
+++ b/spanner/google/cloud/spanner_v1/proto/keys.proto
@@ -0,0 +1,163 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.v1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/struct.proto";
+
+option csharp_namespace = "Google.Cloud.Spanner.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner";
+option java_multiple_files = true;
+option java_outer_classname = "KeysProto";
+option java_package = "com.google.spanner.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\V1";
+
+
+// KeyRange represents a range of rows in a table or index.
+//
+// A range has a start key and an end key. These keys can be open or
+// closed, indicating if the range includes rows with that key.
+//
+// Keys are represented by lists, where the ith value in the list
+// corresponds to the ith component of the table or index primary key.
+// Individual values are encoded as described [here][google.spanner.v1.TypeCode].
+//
+// For example, consider the following table definition:
+//
+//     CREATE TABLE UserEvents (
+//       UserName STRING(MAX),
+//       EventDate STRING(10)
+//     ) PRIMARY KEY(UserName, EventDate);
+//
+// The following keys name rows in this table:
+//
+//     ["Bob", "2014-09-23"]
+//     ["Alfred", "2015-06-12"]
+//
+// Since the `UserEvents` table's `PRIMARY KEY` clause names two
+// columns, each `UserEvents` key has two elements; the first is the
+// `UserName`, and the second is the `EventDate`.
+//
+// Key ranges with multiple components are interpreted
+// lexicographically by component using the table or index key's declared
+// sort order. For example, the following range returns all events for
+// user `"Bob"` that occurred in the year 2015:
+//
+//     "start_closed": ["Bob", "2015-01-01"]
+//     "end_closed": ["Bob", "2015-12-31"]
+//
+// Start and end keys can omit trailing key components. This affects the
+// inclusion and exclusion of rows that exactly match the provided key
+// components: if the key is closed, then rows that exactly match the
+// provided components are included; if the key is open, then rows
+// that exactly match are not included.
+//
+// For example, the following range includes all events for `"Bob"` that
+// occurred during and after the year 2000:
+//
+//     "start_closed": ["Bob", "2000-01-01"]
+//     "end_closed": ["Bob"]
+//
+// The next example retrieves all events for `"Bob"`:
+//
+//     "start_closed": ["Bob"]
+//     "end_closed": ["Bob"]
+//
+// To retrieve events before the year 2000:
+//
+//     "start_closed": ["Bob"]
+//     "end_open": ["Bob", "2000-01-01"]
+//
+// The following range includes all rows in the table:
+//
+//     "start_closed": []
+//     "end_closed": []
+//
+// This range returns all users whose `UserName` begins with any
+// character from A to C:
+//
+//     "start_closed": ["A"]
+//     "end_open": ["D"]
+//
+// This range returns all users whose `UserName` begins with B:
+//
+//     "start_closed": ["B"]
+//     "end_open": ["C"]
+//
+// Key ranges honor column sort order. For example, suppose a table is
+// defined as follows:
+//
+//     CREATE TABLE DescendingSortedTable {
+//       Key INT64,
+//       ...
+//     ) PRIMARY KEY(Key DESC);
+//
+// The following range retrieves all rows with key values between 1
+// and 100 inclusive:
+//
+//     "start_closed": ["100"]
+//     "end_closed": ["1"]
+//
+// Note that 100 is passed as the start, and 1 is passed as the end,
+// because `Key` is a descending column in the schema.
+message KeyRange {
+  // The start key must be provided. It can be either closed or open.
+  oneof start_key_type {
+    // If the start is closed, then the range includes all rows whose
+    // first `len(start_closed)` key columns exactly match `start_closed`.
+    google.protobuf.ListValue start_closed = 1;
+
+    // If the start is open, then the range excludes rows whose first
+    // `len(start_open)` key columns exactly match `start_open`.
+    google.protobuf.ListValue start_open = 2;
+  }
+
+  // The end key must be provided. It can be either closed or open.
+  oneof end_key_type {
+    // If the end is closed, then the range includes all rows whose
+    // first `len(end_closed)` key columns exactly match `end_closed`.
+    google.protobuf.ListValue end_closed = 3;
+
+    // If the end is open, then the range excludes rows whose first
+    // `len(end_open)` key columns exactly match `end_open`.
+    google.protobuf.ListValue end_open = 4;
+  }
+}
+
+// `KeySet` defines a collection of Cloud Spanner keys and/or key ranges. All
+// the keys are expected to be in the same table or index. The keys need
+// not be sorted in any particular way.
+//
+// If the same key is specified multiple times in the set (for example
+// if two ranges, two keys, or a key and a range overlap), Cloud Spanner
+// behaves as if the key were only specified once.
+message KeySet {
+  // A list of specific keys. Entries in `keys` should have exactly as
+  // many elements as there are columns in the primary or index key
+  // with which this `KeySet` is used.  Individual key values are
+  // encoded as described [here][google.spanner.v1.TypeCode].
+  repeated google.protobuf.ListValue keys = 1;
+
+  // A list of key ranges. See [KeyRange][google.spanner.v1.KeyRange] for more information about
+  // key range specifications.
+  repeated KeyRange ranges = 2;
+
+  // For convenience `all` can be set to `true` to indicate that this
+  // `KeySet` matches all keys in the table or index. Note that any keys
+  // specified in `keys` or `ranges` are only yielded once.
+  bool all = 3;
+}
diff --git a/spanner/google/cloud/spanner_v1/proto/mutation.proto b/spanner/google/cloud/spanner_v1/proto/mutation.proto
new file mode 100644
index 000000000000..d4d5354c9965
--- /dev/null
+++ b/spanner/google/cloud/spanner_v1/proto/mutation.proto
@@ -0,0 +1,95 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.v1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/struct.proto";
+import "google/spanner/v1/keys.proto";
+
+option csharp_namespace = "Google.Cloud.Spanner.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner";
+option java_multiple_files = true;
+option java_outer_classname = "MutationProto";
+option java_package = "com.google.spanner.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\V1";
+
+
+// A modification to one or more Cloud Spanner rows.  Mutations can be
+// applied to a Cloud Spanner database by sending them in a
+// [Commit][google.spanner.v1.Spanner.Commit] call.
+message Mutation {
+  // Arguments to [insert][google.spanner.v1.Mutation.insert], [update][google.spanner.v1.Mutation.update], [insert_or_update][google.spanner.v1.Mutation.insert_or_update], and
+  // [replace][google.spanner.v1.Mutation.replace] operations.
+  message Write {
+    // Required. The table whose rows will be written.
+    string table = 1;
+
+    // The names of the columns in [table][google.spanner.v1.Mutation.Write.table] to be written.
+    //
+    // The list of columns must contain enough columns to allow
+    // Cloud Spanner to derive values for all primary key columns in the
+    // row(s) to be modified.
+    repeated string columns = 2;
+
+    // The values to be written. `values` can contain more than one
+    // list of values. If it does, then multiple rows are written, one
+    // for each entry in `values`. Each list in `values` must have
+    // exactly as many entries as there are entries in [columns][google.spanner.v1.Mutation.Write.columns]
+    // above. Sending multiple lists is equivalent to sending multiple
+    // `Mutation`s, each containing one `values` entry and repeating
+    // [table][google.spanner.v1.Mutation.Write.table] and [columns][google.spanner.v1.Mutation.Write.columns]. Individual values in each list are
+    // encoded as described [here][google.spanner.v1.TypeCode].
+    repeated google.protobuf.ListValue values = 3;
+  }
+
+  // Arguments to [delete][google.spanner.v1.Mutation.delete] operations.
+  message Delete {
+    // Required. The table whose rows will be deleted.
+    string table = 1;
+
+    // Required. The primary keys of the rows within [table][google.spanner.v1.Mutation.Delete.table] to delete.
+    // Delete is idempotent. The transaction will succeed even if some or all
+    // rows do not exist.
+    KeySet key_set = 2;
+  }
+
+  // Required. The operation to perform.
+  oneof operation {
+    // Insert new rows in a table. If any of the rows already exist,
+    // the write or transaction fails with error `ALREADY_EXISTS`.
+    Write insert = 1;
+
+    // Update existing rows in a table. If any of the rows does not
+    // already exist, the transaction fails with error `NOT_FOUND`.
+    Write update = 2;
+
+    // Like [insert][google.spanner.v1.Mutation.insert], except that if the row already exists, then
+    // its column values are overwritten with the ones provided. Any
+    // column values not explicitly written are preserved.
+    Write insert_or_update = 3;
+
+    // Like [insert][google.spanner.v1.Mutation.insert], except that if the row already exists, it is
+    // deleted, and the column values provided are inserted
+    // instead. Unlike [insert_or_update][google.spanner.v1.Mutation.insert_or_update], this means any values not
+    // explicitly written become `NULL`.
+    Write replace = 4;
+
+    // Delete rows from a table. Succeeds whether or not the named
+    // rows were present.
+    Delete delete = 5;
+  }
+}
diff --git a/spanner/google/cloud/spanner_v1/proto/query_plan.proto b/spanner/google/cloud/spanner_v1/proto/query_plan.proto
new file mode 100644
index 000000000000..7e82a404fc42
--- /dev/null
+++ b/spanner/google/cloud/spanner_v1/proto/query_plan.proto
@@ -0,0 +1,129 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.v1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/struct.proto";
+
+option csharp_namespace = "Google.Cloud.Spanner.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner";
+option java_multiple_files = true;
+option java_outer_classname = "QueryPlanProto";
+option java_package = "com.google.spanner.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\V1";
+
+
+// Node information for nodes appearing in a [QueryPlan.plan_nodes][google.spanner.v1.QueryPlan.plan_nodes].
+message PlanNode {
+  // Metadata associated with a parent-child relationship appearing in a
+  // [PlanNode][google.spanner.v1.PlanNode].
+  message ChildLink {
+    // The node to which the link points.
+    int32 child_index = 1;
+
+    // The type of the link. For example, in Hash Joins this could be used to
+    // distinguish between the build child and the probe child, or in the case
+    // of the child being an output variable, to represent the tag associated
+    // with the output variable.
+    string type = 2;
+
+    // Only present if the child node is [SCALAR][google.spanner.v1.PlanNode.Kind.SCALAR] and corresponds
+    // to an output variable of the parent node. The field carries the name of
+    // the output variable.
+    // For example, a `TableScan` operator that reads rows from a table will
+    // have child links to the `SCALAR` nodes representing the output variables
+    // created for each column that is read by the operator. The corresponding
+    // `variable` fields will be set to the variable names assigned to the
+    // columns.
+    string variable = 3;
+  }
+
+  // Condensed representation of a node and its subtree. Only present for
+  // `SCALAR` [PlanNode(s)][google.spanner.v1.PlanNode].
+  message ShortRepresentation {
+    // A string representation of the expression subtree rooted at this node.
+    string description = 1;
+
+    // A mapping of (subquery variable name) -> (subquery node id) for cases
+    // where the `description` string of this node references a `SCALAR`
+    // subquery contained in the expression subtree rooted at this node. The
+    // referenced `SCALAR` subquery may not necessarily be a direct child of
+    // this node.
+    map<string, int32> subqueries = 2;
+  }
+
+  // The kind of [PlanNode][google.spanner.v1.PlanNode]. Distinguishes between the two different kinds of
+  // nodes that can appear in a query plan.
+  enum Kind {
+    // Not specified.
+    KIND_UNSPECIFIED = 0;
+
+    // Denotes a Relational operator node in the expression tree. Relational
+    // operators represent iterative processing of rows during query execution.
+    // For example, a `TableScan` operation that reads rows from a table.
+    RELATIONAL = 1;
+
+    // Denotes a Scalar node in the expression tree. Scalar nodes represent
+    // non-iterable entities in the query plan. For example, constants or
+    // arithmetic operators appearing inside predicate expressions or references
+    // to column names.
+    SCALAR = 2;
+  }
+
+  // The `PlanNode`'s index in [node list][google.spanner.v1.QueryPlan.plan_nodes].
+  int32 index = 1;
+
+  // Used to determine the type of node. May be needed for visualizing
+  // different kinds of nodes differently. For example, If the node is a
+  // [SCALAR][google.spanner.v1.PlanNode.Kind.SCALAR] node, it will have a condensed representation
+  // which can be used to directly embed a description of the node in its
+  // parent.
+  Kind kind = 2;
+
+  // The display name for the node.
+  string display_name = 3;
+
+  // List of child node `index`es and their relationship to this parent.
+  repeated ChildLink child_links = 4;
+
+  // Condensed representation for [SCALAR][google.spanner.v1.PlanNode.Kind.SCALAR] nodes.
+  ShortRepresentation short_representation = 5;
+
+  // Attributes relevant to the node contained in a group of key-value pairs.
+  // For example, a Parameter Reference node could have the following
+  // information in its metadata:
+  //
+  //     {
+  //       "parameter_reference": "param1",
+  //       "parameter_type": "array"
+  //     }
+  google.protobuf.Struct metadata = 6;
+
+  // The execution statistics associated with the node, contained in a group of
+  // key-value pairs. Only present if the plan was returned as a result of a
+  // profile query. For example, number of executions, number of rows/time per
+  // execution etc.
+  google.protobuf.Struct execution_stats = 7;
+}
+
+// Contains an ordered list of nodes appearing in the query plan.
+message QueryPlan {
+  // The nodes in the query plan. Plan nodes are returned in pre-order starting
+  // with the plan root. Each [PlanNode][google.spanner.v1.PlanNode]'s `id` corresponds to its index in
+  // `plan_nodes`.
+  repeated PlanNode plan_nodes = 1;
+}
diff --git a/spanner/google/cloud/spanner_v1/proto/result_set.proto b/spanner/google/cloud/spanner_v1/proto/result_set.proto
new file mode 100644
index 000000000000..152b1368a2ec
--- /dev/null
+++ b/spanner/google/cloud/spanner_v1/proto/result_set.proto
@@ -0,0 +1,205 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.v1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/struct.proto";
+import "google/spanner/v1/query_plan.proto";
+import "google/spanner/v1/transaction.proto";
+import "google/spanner/v1/type.proto";
+
+option cc_enable_arenas = true;
+option csharp_namespace = "Google.Cloud.Spanner.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner";
+option java_multiple_files = true;
+option java_outer_classname = "ResultSetProto";
+option java_package = "com.google.spanner.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\V1";
+
+
+// Results from [Read][google.spanner.v1.Spanner.Read] or
+// [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql].
+message ResultSet {
+  // Metadata about the result set, such as row type information.
+  ResultSetMetadata metadata = 1;
+
+  // Each element in `rows` is a row whose format is defined by
+  // [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
+  // in each row matches the ith field in
+  // [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
+  // encoded based on type as described
+  // [here][google.spanner.v1.TypeCode].
+  repeated google.protobuf.ListValue rows = 2;
+
+  // Query plan and execution statistics for the SQL statement that
+  // produced this result set. These can be requested by setting
+  // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode].
+  // DML statements always produce stats containing the number of rows
+  // modified, unless executed using the
+  // [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode].
+  // Other fields may or may not be populated, based on the
+  // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode].
+  ResultSetStats stats = 3;
+}
+
+// Partial results from a streaming read or SQL query. Streaming reads and
+// SQL queries better tolerate large result sets, large rows, and large
+// values, but are a little trickier to consume.
+message PartialResultSet {
+  // Metadata about the result set, such as row type information.
+  // Only present in the first response.
+  ResultSetMetadata metadata = 1;
+
+  // A streamed result set consists of a stream of values, which might
+  // be split into many `PartialResultSet` messages to accommodate
+  // large rows and/or large values. Every N complete values defines a
+  // row, where N is equal to the number of entries in
+  // [metadata.row_type.fields][google.spanner.v1.StructType.fields].
+  //
+  // Most values are encoded based on type as described
+  // [here][google.spanner.v1.TypeCode].
+  //
+  // It is possible that the last value in values is "chunked",
+  // meaning that the rest of the value is sent in subsequent
+  // `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value]
+  // field. Two or more chunked values can be merged to form a
+  // complete value as follows:
+  //
+  //   * `bool/number/null`: cannot be chunked
+  //   * `string`: concatenate the strings
+  //   * `list`: concatenate the lists. If the last element in a list is a
+  //     `string`, `list`, or `object`, merge it with the first element in
+  //     the next list by applying these rules recursively.
+  //   * `object`: concatenate the (field name, field value) pairs. If a
+  //     field name is duplicated, then apply these rules recursively
+  //     to merge the field values.
+  //
+  // Some examples of merging:
+  //
+  //     # Strings are concatenated.
+  //     "foo", "bar" => "foobar"
+  //
+  //     # Lists of non-strings are concatenated.
+  //     [2, 3], [4] => [2, 3, 4]
+  //
+  //     # Lists are concatenated, but the last and first elements are merged
+  //     # because they are strings.
+  //     ["a", "b"], ["c", "d"] => ["a", "bc", "d"]
+  //
+  //     # Lists are concatenated, but the last and first elements are merged
+  //     # because they are lists. Recursively, the last and first elements
+  //     # of the inner lists are merged because they are strings.
+  //     ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"]
+  //
+  //     # Non-overlapping object fields are combined.
+  //     {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"}
+  //
+  //     # Overlapping object fields are merged.
+  //     {"a": "1"}, {"a": "2"} => {"a": "12"}
+  //
+  //     # Examples of merging objects containing lists of strings.
+  //     {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]}
+  //
+  // For a more complete example, suppose a streaming SQL query is
+  // yielding a result set whose rows contain a single string
+  // field. The following `PartialResultSet`s might be yielded:
+  //
+  //     {
+  //       "metadata": { ... }
+  //       "values": ["Hello", "W"]
+  //       "chunked_value": true
+  //       "resume_token": "Af65..."
+  //     }
+  //     {
+  //       "values": ["orl"]
+  //       "chunked_value": true
+  //       "resume_token": "Bqp2..."
+  //     }
+  //     {
+  //       "values": ["d"]
+  //       "resume_token": "Zx1B..."
+  //     }
+  //
+  // This sequence of `PartialResultSet`s encodes two rows, one
+  // containing the field value `"Hello"`, and a second containing the
+  // field value `"World" = "W" + "orl" + "d"`.
+  repeated google.protobuf.Value values = 2;
+
+  // If true, then the final value in [values][google.spanner.v1.PartialResultSet.values] is chunked, and must
+  // be combined with more values from subsequent `PartialResultSet`s
+  // to obtain a complete field value.
+  bool chunked_value = 3;
+
+  // Streaming calls might be interrupted for a variety of reasons, such
+  // as TCP connection loss. If this occurs, the stream of results can
+  // be resumed by re-sending the original request and including
+  // `resume_token`. Note that executing any other transaction in the
+  // same session invalidates the token.
+  bytes resume_token = 4;
+
+  // Query plan and execution statistics for the statement that produced this
+  // streaming result set. These can be requested by setting
+  // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
+  // only once with the last response in the stream.
+  // This field will also be present in the last response for DML
+  // statements.
+  ResultSetStats stats = 5;
+}
+
+// Metadata about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet].
+message ResultSetMetadata {
+  // Indicates the field names and types for the rows in the result
+  // set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+  // Users"` could return a `row_type` value like:
+  //
+  //     "fields": [
+  //       { "name": "UserId", "type": { "code": "INT64" } },
+  //       { "name": "UserName", "type": { "code": "STRING" } },
+  //     ]
+  StructType row_type = 1;
+
+  // If the read or SQL query began a transaction as a side-effect, the
+  // information about the new transaction is yielded here.
+  Transaction transaction = 2;
+}
+
+// Additional statistics about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet].
+message ResultSetStats {
+  // [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+  QueryPlan query_plan = 1;
+
+  // Aggregated statistics from the execution of the query. Only present when
+  // the query is profiled. For example, a query could return the statistics as
+  // follows:
+  //
+  //     {
+  //       "rows_returned": "3",
+  //       "elapsed_time": "1.22 secs",
+  //       "cpu_time": "1.19 secs"
+  //     }
+  google.protobuf.Struct query_stats = 2;
+
+  // The number of rows modified by the DML statement.
+  oneof row_count {
+    // Standard DML returns an exact count of rows that were modified.
+    int64 row_count_exact = 3;
+
+    // Partitioned DML does not offer exactly-once semantics, so it
+    // returns a lower bound of the rows modified.
+    int64 row_count_lower_bound = 4;
+  }
+}
diff --git a/spanner/google/cloud/spanner_v1/proto/spanner.proto b/spanner/google/cloud/spanner_v1/proto/spanner.proto
new file mode 100644
index 000000000000..7d3de6ad771e
--- /dev/null
+++ b/spanner/google/cloud/spanner_v1/proto/spanner.proto
@@ -0,0 +1,645 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.v1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+import "google/spanner/v1/keys.proto";
+import "google/spanner/v1/mutation.proto";
+import "google/spanner/v1/result_set.proto";
+import "google/spanner/v1/transaction.proto";
+import "google/spanner/v1/type.proto";
+
+option csharp_namespace = "Google.Cloud.Spanner.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner";
+option java_multiple_files = true;
+option java_outer_classname = "SpannerProto";
+option java_package = "com.google.spanner.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\V1";
+
+
+// Cloud Spanner API
+//
+// The Cloud Spanner API can be used to manage sessions and execute
+// transactions on data stored in Cloud Spanner databases.
+service Spanner {
+  // Creates a new session. A session can be used to perform
+  // transactions that read and/or modify data in a Cloud Spanner database.
+  // Sessions are meant to be reused for many consecutive
+  // transactions.
+  //
+  // Sessions can only execute one transaction at a time. To execute
+  // multiple concurrent read-write/write-only transactions, create
+  // multiple sessions. Note that standalone reads and queries use a
+  // transaction internally, and count toward the one transaction
+  // limit.
+  //
+  // Cloud Spanner limits the number of sessions that can exist at any given
+  // time; thus, it is a good idea to delete idle and/or unneeded sessions.
+  // Aside from explicit deletes, Cloud Spanner can delete sessions for which no
+  // operations are sent for more than an hour. If a session is deleted,
+  // requests to it return `NOT_FOUND`.
+  //
+  // Idle sessions can be kept alive by sending a trivial SQL query
+  // periodically, e.g., `"SELECT 1"`.
+  rpc CreateSession(CreateSessionRequest) returns (Session) {
+    option (google.api.http) = {
+      post: "/v1/{database=projects/*/instances/*/databases/*}/sessions"
+      body: "*"
+    };
+  }
+
+  // Gets a session. Returns `NOT_FOUND` if the session does not exist.
+  // This is mainly useful for determining whether a session is still
+  // alive.
+  rpc GetSession(GetSessionRequest) returns (Session) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/instances/*/databases/*/sessions/*}"
+    };
+  }
+
+  // Lists all sessions in a given database.
+  rpc ListSessions(ListSessionsRequest) returns (ListSessionsResponse) {
+    option (google.api.http) = {
+      get: "/v1/{database=projects/*/instances/*/databases/*}/sessions"
+    };
+  }
+
+  // Ends a session, releasing server resources associated with it.
+  rpc DeleteSession(DeleteSessionRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1/{name=projects/*/instances/*/databases/*/sessions/*}"
+    };
+  }
+
+  // Executes an SQL statement, returning all results in a single reply. This
+  // method cannot be used to return a result set larger than 10 MiB;
+  // if the query yields more data than that, the query fails with
+  // a `FAILED_PRECONDITION` error.
+  //
+  // Operations inside read-write transactions might return `ABORTED`. If
+  // this occurs, the application should restart the transaction from
+  // the beginning. See [Transaction][google.spanner.v1.Transaction] for more details.
+  //
+  // Larger result sets can be fetched in streaming fashion by calling
+  // [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] instead.
+  rpc ExecuteSql(ExecuteSqlRequest) returns (ResultSet) {
+    option (google.api.http) = {
+      post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:executeSql"
+      body: "*"
+    };
+  }
+
+  // Like [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], except returns the result
+  // set as a stream. Unlike [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], there
+  // is no limit on the size of the returned result set. However, no
+  // individual row in the result set can exceed 100 MiB, and no
+  // column value can exceed 10 MiB.
+  rpc ExecuteStreamingSql(ExecuteSqlRequest) returns (stream PartialResultSet) {
+    option (google.api.http) = {
+      post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:executeStreamingSql"
+      body: "*"
+    };
+  }
+
+  // Reads rows from the database using key lookups and scans, as a
+  // simple key/value style alternative to
+  // [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql].  This method cannot be used to
+  // return a result set larger than 10 MiB; if the read matches more
+  // data than that, the read fails with a `FAILED_PRECONDITION`
+  // error.
+  //
+  // Reads inside read-write transactions might return `ABORTED`. If
+  // this occurs, the application should restart the transaction from
+  // the beginning. See [Transaction][google.spanner.v1.Transaction] for more details.
+  //
+  // Larger result sets can be yielded in streaming fashion by calling
+  // [StreamingRead][google.spanner.v1.Spanner.StreamingRead] instead.
+  rpc Read(ReadRequest) returns (ResultSet) {
+    option (google.api.http) = {
+      post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:read"
+      body: "*"
+    };
+  }
+
+  // Like [Read][google.spanner.v1.Spanner.Read], except returns the result set as a
+  // stream. Unlike [Read][google.spanner.v1.Spanner.Read], there is no limit on the
+  // size of the returned result set. However, no individual row in
+  // the result set can exceed 100 MiB, and no column value can exceed
+  // 10 MiB.
+  rpc StreamingRead(ReadRequest) returns (stream PartialResultSet) {
+    option (google.api.http) = {
+      post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:streamingRead"
+      body: "*"
+    };
+  }
+
+  // Begins a new transaction. This step can often be skipped:
+  // [Read][google.spanner.v1.Spanner.Read], [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and
+  // [Commit][google.spanner.v1.Spanner.Commit] can begin a new transaction as a
+  // side-effect.
+  rpc BeginTransaction(BeginTransactionRequest) returns (Transaction) {
+    option (google.api.http) = {
+      post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:beginTransaction"
+      body: "*"
+    };
+  }
+
+  // Commits a transaction. The request includes the mutations to be
+  // applied to rows in the database.
+  //
+  // `Commit` might return an `ABORTED` error. This can occur at any time;
+  // commonly, the cause is conflicts with concurrent
+  // transactions. However, it can also happen for a variety of other
+  // reasons. If `Commit` returns `ABORTED`, the caller should re-attempt
+  // the transaction from the beginning, re-using the same session.
+  rpc Commit(CommitRequest) returns (CommitResponse) {
+    option (google.api.http) = {
+      post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:commit"
+      body: "*"
+    };
+  }
+
+  // Rolls back a transaction, releasing any locks it holds. It is a good
+  // idea to call this for any transaction that includes one or more
+  // [Read][google.spanner.v1.Spanner.Read] or [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] requests and
+  // ultimately decides not to commit.
+  //
+  // `Rollback` returns `OK` if it successfully aborts the transaction, the
+  // transaction was already aborted, or the transaction is not
+  // found. `Rollback` never returns `ABORTED`.
+  rpc Rollback(RollbackRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:rollback"
+      body: "*"
+    };
+  }
+
+  // Creates a set of partition tokens that can be used to execute a query
+  // operation in parallel.  Each of the returned partition tokens can be used
+  // by [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] to specify a subset
+  // of the query result to read.  The same session and read-only transaction
+  // must be used by the PartitionQueryRequest used to create the
+  // partition tokens and the ExecuteSqlRequests that use the partition tokens.
+  //
+  // Partition tokens become invalid when the session used to create them
+  // is deleted, is idle for too long, begins a new transaction, or becomes too
+  // old.  When any of these happen, it is not possible to resume the query, and
+  // the whole operation must be restarted from the beginning.
+  rpc PartitionQuery(PartitionQueryRequest) returns (PartitionResponse) {
+    option (google.api.http) = {
+      post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:partitionQuery"
+      body: "*"
+    };
+  }
+
+  // Creates a set of partition tokens that can be used to execute a read
+  // operation in parallel.  Each of the returned partition tokens can be used
+  // by [StreamingRead][google.spanner.v1.Spanner.StreamingRead] to specify a subset of the read
+  // result to read.  The same session and read-only transaction must be used by
+  // the PartitionReadRequest used to create the partition tokens and the
+  // ReadRequests that use the partition tokens.  There are no ordering
+  // guarantees on rows returned among the returned partition tokens, or even
+  // within each individual StreamingRead call issued with a partition_token.
+  //
+  // Partition tokens become invalid when the session used to create them
+  // is deleted, is idle for too long, begins a new transaction, or becomes too
+  // old.  When any of these happen, it is not possible to resume the read, and
+  // the whole operation must be restarted from the beginning.
+  rpc PartitionRead(PartitionReadRequest) returns (PartitionResponse) {
+    option (google.api.http) = {
+      post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:partitionRead"
+      body: "*"
+    };
+  }
+}
+
+// The request for [CreateSession][google.spanner.v1.Spanner.CreateSession].
+message CreateSessionRequest {
+  // Required. The database in which the new session is created.
+  string database = 1;
+
+  // The session to create.
+  Session session = 2;
+}
+
+// A session in the Cloud Spanner API.
+message Session {
+  // The name of the session. This is always system-assigned; values provided
+  // when creating a session are ignored.
+  string name = 1;
+
+  // The labels for the session.
+  //
+  //  * Label keys must be between 1 and 63 characters long and must conform to
+  //    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+  //  * Label values must be between 0 and 63 characters long and must conform
+  //    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+  //  * No more than 64 labels can be associated with a given session.
+  //
+  // See https://goo.gl/xmQnxf for more information on and examples of labels.
+  map<string, string> labels = 2;
+
+  // Output only. The timestamp when the session is created.
+  google.protobuf.Timestamp create_time = 3;
+
+  // Output only. The approximate timestamp when the session is last used. It is
+  // typically earlier than the actual last use time.
+  google.protobuf.Timestamp approximate_last_use_time = 4;
+}
+
+// The request for [GetSession][google.spanner.v1.Spanner.GetSession].
+message GetSessionRequest {
+  // Required. The name of the session to retrieve.
+  string name = 1;
+}
+
+// The request for [ListSessions][google.spanner.v1.Spanner.ListSessions].
+message ListSessionsRequest {
+  // Required. The database in which to list sessions.
+  string database = 1;
+
+  // Number of sessions to be returned in the response. If 0 or less, defaults
+  // to the server's maximum allowed page size.
+  int32 page_size = 2;
+
+  // If non-empty, `page_token` should contain a
+  // [next_page_token][google.spanner.v1.ListSessionsResponse.next_page_token] from a previous
+  // [ListSessionsResponse][google.spanner.v1.ListSessionsResponse].
+  string page_token = 3;
+
+  // An expression for filtering the results of the request. Filter rules are
+  // case insensitive. The fields eligible for filtering are:
+  //
+  //   * `labels.key` where key is the name of a label
+  //
+  // Some examples of using filters are:
+  //
+  //   * `labels.env:*` --> The session has the label "env".
+  //   * `labels.env:dev` --> The session has the label "env" and the value of
+  //                        the label contains the string "dev".
+  string filter = 4;
+}
+
+// The response for [ListSessions][google.spanner.v1.Spanner.ListSessions].
+message ListSessionsResponse {
+  // The list of requested sessions.
+  repeated Session sessions = 1;
+
+  // `next_page_token` can be sent in a subsequent
+  // [ListSessions][google.spanner.v1.Spanner.ListSessions] call to fetch more of the matching
+  // sessions.
+  string next_page_token = 2;
+}
+
+// The request for [DeleteSession][google.spanner.v1.Spanner.DeleteSession].
+message DeleteSessionRequest {
+  // Required. The name of the session to delete.
+  string name = 1;
+}
+
+// The request for [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and
+// [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql].
+message ExecuteSqlRequest {
+  // Mode in which the statement must be processed.
+  enum QueryMode {
+    // The default mode. Only the statement results are returned.
+    NORMAL = 0;
+
+    // This mode returns only the query plan, without any results or
+    // execution statistics information.
+    PLAN = 1;
+
+    // This mode returns both the query plan and the execution statistics along
+    // with the results.
+    PROFILE = 2;
+  }
+
+  // Required. The session in which the SQL query should be performed.
+  string session = 1;
+
+  // The transaction to use. If none is provided, the default is a
+  // temporary read-only transaction with strong concurrency.
+  //
+  // The transaction to use.
+  //
+  // For queries, if none is provided, the default is a temporary read-only
+  // transaction with strong concurrency.
+  //
+  // Standard DML statements require a ReadWrite transaction. Single-use
+  // transactions are not supported (to avoid replay).  The caller must
+  // either supply an existing transaction ID or begin a new transaction.
+  //
+  // Partitioned DML requires an existing PartitionedDml transaction ID.
+  TransactionSelector transaction = 2;
+
+  // Required. The SQL string.
+  string sql = 3;
+
+  // The SQL string can contain parameter placeholders. A parameter
+  // placeholder consists of `'@'` followed by the parameter
+  // name. Parameter names consist of any combination of letters,
+  // numbers, and underscores.
+  //
+  // Parameters can appear anywhere that a literal value is expected.  The same
+  // parameter name can be used more than once, for example:
+  //   `"WHERE id > @msg_id AND id < @msg_id + 100"`
+  //
+  // It is an error to execute an SQL statement with unbound parameters.
+  //
+  // Parameter values are specified using `params`, which is a JSON
+  // object whose keys are parameter names, and whose values are the
+  // corresponding parameter values.
+  google.protobuf.Struct params = 4;
+
+  // It is not always possible for Cloud Spanner to infer the right SQL type
+  // from a JSON value.  For example, values of type `BYTES` and values
+  // of type `STRING` both appear in [params][google.spanner.v1.ExecuteSqlRequest.params] as JSON strings.
+  //
+  // In these cases, `param_types` can be used to specify the exact
+  // SQL type for some or all of the SQL statement parameters. See the
+  // definition of [Type][google.spanner.v1.Type] for more information
+  // about SQL types.
+  map<string, Type> param_types = 5;
+
+  // If this request is resuming a previously interrupted SQL statement
+  // execution, `resume_token` should be copied from the last
+  // [PartialResultSet][google.spanner.v1.PartialResultSet] yielded before the interruption. Doing this
+  // enables the new SQL statement execution to resume where the last one left
+  // off. The rest of the request parameters must exactly match the
+  // request that yielded this token.
+  bytes resume_token = 6;
+
+  // Used to control the amount of debugging information returned in
+  // [ResultSetStats][google.spanner.v1.ResultSetStats]. If [partition_token][google.spanner.v1.ExecuteSqlRequest.partition_token] is set, [query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] can only
+  // be set to [QueryMode.NORMAL][google.spanner.v1.ExecuteSqlRequest.QueryMode.NORMAL].
+  QueryMode query_mode = 7;
+
+  // If present, results will be restricted to the specified partition
+  // previously created using PartitionQuery().  There must be an exact
+  // match for the values of fields common to this message and the
+  // PartitionQueryRequest message used to create this partition_token.
+  bytes partition_token = 8;
+
+  // A per-transaction sequence number used to identify this request. This
+  // makes each request idempotent such that if the request is received multiple
+  // times, at most one will succeed.
+  //
+  // The sequence number must be monotonically increasing within the
+  // transaction. If a request arrives for the first time with an out-of-order
+  // sequence number, the transaction may be aborted. Replays of previously
+  // handled requests will yield the same response as the first execution.
+  //
+  // Required for DML statements. Ignored for queries.
+  int64 seqno = 9;
+}
+
+// Options for a PartitionQueryRequest and
+// PartitionReadRequest.
+message PartitionOptions {
+  // **Note:** This hint is currently ignored by PartitionQuery and
+  // PartitionRead requests.
+  //
+  // The desired data size for each partition generated.  The default for this
+  // option is currently 1 GiB.  This is only a hint. The actual size of each
+  // partition may be smaller or larger than this size request.
+  int64 partition_size_bytes = 1;
+
+  // **Note:** This hint is currently ignored by PartitionQuery and
+  // PartitionRead requests.
+  //
+  // The desired maximum number of partitions to return.  For example, this may
+  // be set to the number of workers available.  The default for this option
+  // is currently 10,000. The maximum value is currently 200,000.  This is only
+  // a hint.  The actual number of partitions returned may be smaller or larger
+  // than this maximum count request.
+  int64 max_partitions = 2;
+}
+
+// The request for [PartitionQuery][google.spanner.v1.Spanner.PartitionQuery]
+message PartitionQueryRequest {
+  // Required. The session used to create the partitions.
+  string session = 1;
+
+  // Read only snapshot transactions are supported, read/write and single use
+  // transactions are not.
+  TransactionSelector transaction = 2;
+
+  // The query request to generate partitions for. The request will fail if
+  // the query is not root partitionable. The query plan of a root
+  // partitionable query has a single distributed union operator. A distributed
+  // union operator conceptually divides one or more tables into multiple
+  // splits, remotely evaluates a subquery independently on each split, and
+  // then unions all results.
+  //
+  // This must not contain DML commands, such as INSERT, UPDATE, or
+  // DELETE. Use [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] with a
+  // PartitionedDml transaction for large, partition-friendly DML operations.
+  string sql = 3;
+
+  // The SQL query string can contain parameter placeholders. A parameter
+  // placeholder consists of `'@'` followed by the parameter
+  // name. Parameter names consist of any combination of letters,
+  // numbers, and underscores.
+  //
+  // Parameters can appear anywhere that a literal value is expected.  The same
+  // parameter name can be used more than once, for example:
+  //   `"WHERE id > @msg_id AND id < @msg_id + 100"`
+  //
+  // It is an error to execute an SQL query with unbound parameters.
+  //
+  // Parameter values are specified using `params`, which is a JSON
+  // object whose keys are parameter names, and whose values are the
+  // corresponding parameter values.
+  google.protobuf.Struct params = 4;
+
+  // It is not always possible for Cloud Spanner to infer the right SQL type
+  // from a JSON value.  For example, values of type `BYTES` and values
+  // of type `STRING` both appear in [params][google.spanner.v1.PartitionQueryRequest.params] as JSON strings.
+  //
+  // In these cases, `param_types` can be used to specify the exact
+  // SQL type for some or all of the SQL query parameters. See the
+  // definition of [Type][google.spanner.v1.Type] for more information
+  // about SQL types.
+  map<string, Type> param_types = 5;
+
+  // Additional options that affect how many partitions are created.
+  PartitionOptions partition_options = 6;
+}
+
+// The request for [PartitionRead][google.spanner.v1.Spanner.PartitionRead]
+message PartitionReadRequest {
+  // Required. The session used to create the partitions.
+  string session = 1;
+
+  // Read only snapshot transactions are supported, read/write and single use
+  // transactions are not.
+  TransactionSelector transaction = 2;
+
+  // Required. The name of the table in the database to be read.
+  string table = 3;
+
+  // If non-empty, the name of an index on [table][google.spanner.v1.PartitionReadRequest.table]. This index is
+  // used instead of the table primary key when interpreting [key_set][google.spanner.v1.PartitionReadRequest.key_set]
+  // and sorting result rows. See [key_set][google.spanner.v1.PartitionReadRequest.key_set] for further information.
+  string index = 4;
+
+  // The columns of [table][google.spanner.v1.PartitionReadRequest.table] to be returned for each row matching
+  // this request.
+  repeated string columns = 5;
+
+  // Required. `key_set` identifies the rows to be yielded. `key_set` names the
+  // primary keys of the rows in [table][google.spanner.v1.PartitionReadRequest.table] to be yielded, unless [index][google.spanner.v1.PartitionReadRequest.index]
+  // is present. If [index][google.spanner.v1.PartitionReadRequest.index] is present, then [key_set][google.spanner.v1.PartitionReadRequest.key_set] instead names
+  // index keys in [index][google.spanner.v1.PartitionReadRequest.index].
+  //
+  // It is not an error for the `key_set` to name rows that do not
+  // exist in the database. Read yields nothing for nonexistent rows.
+  KeySet key_set = 6;
+
+  // Additional options that affect how many partitions are created.
+  PartitionOptions partition_options = 9;
+}
+
+// Information returned for each partition returned in a
+// PartitionResponse.
+message Partition {
+  // This token can be passed to Read, StreamingRead, ExecuteSql, or
+  // ExecuteStreamingSql requests to restrict the results to those identified by
+  // this partition token.
+  bytes partition_token = 1;
+}
+
+// The response for [PartitionQuery][google.spanner.v1.Spanner.PartitionQuery]
+// or [PartitionRead][google.spanner.v1.Spanner.PartitionRead]
+message PartitionResponse {
+  // Partitions created by this request.
+  repeated Partition partitions = 1;
+
+  // Transaction created by this request.
+  Transaction transaction = 2;
+}
+
+// The request for [Read][google.spanner.v1.Spanner.Read] and
+// [StreamingRead][google.spanner.v1.Spanner.StreamingRead].
+message ReadRequest {
+  // Required. The session in which the read should be performed.
+  string session = 1;
+
+  // The transaction to use. If none is provided, the default is a
+  // temporary read-only transaction with strong concurrency.
+  TransactionSelector transaction = 2;
+
+  // Required. The name of the table in the database to be read.
+  string table = 3;
+
+  // If non-empty, the name of an index on [table][google.spanner.v1.ReadRequest.table]. This index is
+  // used instead of the table primary key when interpreting [key_set][google.spanner.v1.ReadRequest.key_set]
+  // and sorting result rows. See [key_set][google.spanner.v1.ReadRequest.key_set] for further information.
+  string index = 4;
+
+  // The columns of [table][google.spanner.v1.ReadRequest.table] to be returned for each row matching
+  // this request.
+  repeated string columns = 5;
+
+  // Required. `key_set` identifies the rows to be yielded. `key_set` names the
+  // primary keys of the rows in [table][google.spanner.v1.ReadRequest.table] to be yielded, unless [index][google.spanner.v1.ReadRequest.index]
+  // is present. If [index][google.spanner.v1.ReadRequest.index] is present, then [key_set][google.spanner.v1.ReadRequest.key_set] instead names
+  // index keys in [index][google.spanner.v1.ReadRequest.index].
+  //
+  // If the [partition_token][google.spanner.v1.ReadRequest.partition_token] field is empty, rows are yielded
+  // in table primary key order (if [index][google.spanner.v1.ReadRequest.index] is empty) or index key order
+  // (if [index][google.spanner.v1.ReadRequest.index] is non-empty).  If the [partition_token][google.spanner.v1.ReadRequest.partition_token] field is not
+  // empty, rows will be yielded in an unspecified order.
+  //
+  // It is not an error for the `key_set` to name rows that do not
+  // exist in the database. Read yields nothing for nonexistent rows.
+  KeySet key_set = 6;
+
+  // If greater than zero, only the first `limit` rows are yielded. If `limit`
+  // is zero, the default is no limit. A limit cannot be specified if
+  // `partition_token` is set.
+  int64 limit = 8;
+
+  // If this request is resuming a previously interrupted read,
+  // `resume_token` should be copied from the last
+  // [PartialResultSet][google.spanner.v1.PartialResultSet] yielded before the interruption. Doing this
+  // enables the new read to resume where the last read left off. The
+  // rest of the request parameters must exactly match the request
+  // that yielded this token.
+  bytes resume_token = 9;
+
+  // If present, results will be restricted to the specified partition
+  // previously created using PartitionRead().    There must be an exact
+  // match for the values of fields common to this message and the
+  // PartitionReadRequest message used to create this partition_token.
+  bytes partition_token = 10;
+}
+
+// The request for [BeginTransaction][google.spanner.v1.Spanner.BeginTransaction].
+message BeginTransactionRequest {
+  // Required. The session in which the transaction runs.
+  string session = 1;
+
+  // Required. Options for the new transaction.
+  TransactionOptions options = 2;
+}
+
+// The request for [Commit][google.spanner.v1.Spanner.Commit].
+message CommitRequest {
+  // Required. The session in which the transaction to be committed is running.
+  string session = 1;
+
+  // Required. The transaction in which to commit.
+  oneof transaction {
+    // Commit a previously-started transaction.
+    bytes transaction_id = 2;
+
+    // Execute mutations in a temporary transaction. Note that unlike
+    // commit of a previously-started transaction, commit with a
+    // temporary transaction is non-idempotent. That is, if the
+    // `CommitRequest` is sent to Cloud Spanner more than once (for
+    // instance, due to retries in the application, or in the
+    // transport library), it is possible that the mutations are
+    // executed more than once. If this is undesirable, use
+    // [BeginTransaction][google.spanner.v1.Spanner.BeginTransaction] and
+    // [Commit][google.spanner.v1.Spanner.Commit] instead.
+    TransactionOptions single_use_transaction = 3;
+  }
+
+  // The mutations to be executed when this transaction commits. All
+  // mutations are applied atomically, in the order they appear in
+  // this list.
+  repeated Mutation mutations = 4;
+}
+
+// The response for [Commit][google.spanner.v1.Spanner.Commit].
+message CommitResponse {
+  // The Cloud Spanner timestamp at which the transaction committed.
+  google.protobuf.Timestamp commit_timestamp = 1;
+}
+
+// The request for [Rollback][google.spanner.v1.Spanner.Rollback].
+message RollbackRequest {
+  // Required. The session in which the transaction to roll back is running.
+  string session = 1;
+
+  // Required. The transaction to roll back.
+  bytes transaction_id = 2;
+}
diff --git a/spanner/google/cloud/spanner_v1/proto/spanner_database_admin.proto b/spanner/google/cloud/spanner_v1/proto/spanner_database_admin.proto
new file mode 100644
index 000000000000..56dbff19e17b
--- /dev/null
+++ b/spanner/google/cloud/spanner_v1/proto/spanner_database_admin.proto
@@ -0,0 +1,302 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.admin.database.v1;
+
+import "google/api/annotations.proto";
+import "google/iam/v1/iam_policy.proto";
+import "google/iam/v1/policy.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Spanner.Admin.Database.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/admin/database/v1;database";
+option java_multiple_files = true;
+option java_outer_classname = "SpannerDatabaseAdminProto";
+option java_package = "com.google.spanner.admin.database.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\Admin\\Database\\V1";
+
+
+// Cloud Spanner Database Admin API
+//
+// The Cloud Spanner Database Admin API can be used to create, drop, and
+// list databases. It also enables updating the schema of pre-existing
+// databases.
+service DatabaseAdmin {
+  // Lists Cloud Spanner databases.
+  rpc ListDatabases(ListDatabasesRequest) returns (ListDatabasesResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*/instances/*}/databases"
+    };
+  }
+
+  // Creates a new Cloud Spanner database and starts to prepare it for serving.
+  // The returned [long-running operation][google.longrunning.Operation] will
+  // have a name of the format `<database_name>/operations/<operation_id>` and
+  // can be used to track preparation of the database. The
+  // [metadata][google.longrunning.Operation.metadata] field type is
+  // [CreateDatabaseMetadata][google.spanner.admin.database.v1.CreateDatabaseMetadata]. The
+  // [response][google.longrunning.Operation.response] field type is
+  // [Database][google.spanner.admin.database.v1.Database], if successful.
+  rpc CreateDatabase(CreateDatabaseRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*/instances/*}/databases"
+      body: "*"
+    };
+  }
+
+  // Gets the state of a Cloud Spanner database.
+  rpc GetDatabase(GetDatabaseRequest) returns (Database) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/instances/*/databases/*}"
+    };
+  }
+
+  // Updates the schema of a Cloud Spanner database by
+  // creating/altering/dropping tables, columns, indexes, etc. The returned
+  // [long-running operation][google.longrunning.Operation] will have a name of
+  // the format `<database_name>/operations/<operation_id>` and can be used to
+  // track execution of the schema change(s). The
+  // [metadata][google.longrunning.Operation.metadata] field type is
+  // [UpdateDatabaseDdlMetadata][google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata].  The operation has no response.
+  rpc UpdateDatabaseDdl(UpdateDatabaseDdlRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v1/{database=projects/*/instances/*/databases/*}/ddl"
+      body: "*"
+    };
+  }
+
+  // Drops (aka deletes) a Cloud Spanner database.
+  rpc DropDatabase(DropDatabaseRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1/{database=projects/*/instances/*/databases/*}"
+    };
+  }
+
+  // Returns the schema of a Cloud Spanner database as a list of formatted
+  // DDL statements. This method does not show pending schema updates, those may
+  // be queried using the [Operations][google.longrunning.Operations] API.
+  rpc GetDatabaseDdl(GetDatabaseDdlRequest) returns (GetDatabaseDdlResponse) {
+    option (google.api.http) = {
+      get: "/v1/{database=projects/*/instances/*/databases/*}/ddl"
+    };
+  }
+
+  // Sets the access control policy on a database resource. Replaces any
+  // existing policy.
+  //
+  // Authorization requires `spanner.databases.setIamPolicy` permission on
+  // [resource][google.iam.v1.SetIamPolicyRequest.resource].
+  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*/databases/*}:setIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Gets the access control policy for a database resource. Returns an empty
+  // policy if a database exists but does not have a policy set.
+  //
+  // Authorization requires `spanner.databases.getIamPolicy` permission on
+  // [resource][google.iam.v1.GetIamPolicyRequest.resource].
+  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*/databases/*}:getIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Returns permissions that the caller has on the specified database resource.
+  //
+  // Attempting this RPC on a non-existent Cloud Spanner database will result in
+  // a NOT_FOUND error if the user has `spanner.databases.list` permission on
+  // the containing Cloud Spanner instance. Otherwise returns an empty set of
+  // permissions.
+  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*/databases/*}:testIamPermissions"
+      body: "*"
+    };
+  }
+}
+
+// A Cloud Spanner database.
+message Database {
+  // Indicates the current state of the database.
+  enum State {
+    // Not specified.
+    STATE_UNSPECIFIED = 0;
+
+    // The database is still being created. Operations on the database may fail
+    // with `FAILED_PRECONDITION` in this state.
+    CREATING = 1;
+
+    // The database is fully created and ready for use.
+    READY = 2;
+  }
+
+  // Required. The name of the database. Values are of the form
+  // `projects/<project>/instances/<instance>/databases/<database>`,
+  // where `<database>` is as specified in the `CREATE DATABASE`
+  // statement. This name can be passed to other API methods to
+  // identify the database.
+  string name = 1;
+
+  // Output only. The current database state.
+  State state = 2;
+}
+
+// The request for [ListDatabases][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases].
+message ListDatabasesRequest {
+  // Required. The instance whose databases should be listed.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // Number of databases to be returned in the response. If 0 or less,
+  // defaults to the server's maximum allowed page size.
+  int32 page_size = 3;
+
+  // If non-empty, `page_token` should contain a
+  // [next_page_token][google.spanner.admin.database.v1.ListDatabasesResponse.next_page_token] from a
+  // previous [ListDatabasesResponse][google.spanner.admin.database.v1.ListDatabasesResponse].
+  string page_token = 4;
+}
+
+// The response for [ListDatabases][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases].
+message ListDatabasesResponse {
+  // Databases that matched the request.
+  repeated Database databases = 1;
+
+  // `next_page_token` can be sent in a subsequent
+  // [ListDatabases][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases] call to fetch more
+  // of the matching databases.
+  string next_page_token = 2;
+}
+
+// The request for [CreateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.CreateDatabase].
+message CreateDatabaseRequest {
+  // Required. The name of the instance that will serve the new database.
+  // Values are of the form `projects/<project>/instances/<instance>`.
+  string parent = 1;
+
+  // Required. A `CREATE DATABASE` statement, which specifies the ID of the
+  // new database.  The database ID must conform to the regular expression
+  // `[a-z][a-z0-9_\-]*[a-z0-9]` and be between 2 and 30 characters in length.
+  // If the database ID is a reserved word or if it contains a hyphen, the
+  // database ID must be enclosed in backticks (`` ` ``).
+  string create_statement = 2;
+
+  // An optional list of DDL statements to run inside the newly created
+  // database. Statements can create tables, indexes, etc. These
+  // statements execute atomically with the creation of the database:
+  // if there is an error in any statement, the database is not created.
+  repeated string extra_statements = 3;
+}
+
+// Metadata type for the operation returned by
+// [CreateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.CreateDatabase].
+message CreateDatabaseMetadata {
+  // The database being created.
+  string database = 1;
+}
+
+// The request for [GetDatabase][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabase].
+message GetDatabaseRequest {
+  // Required. The name of the requested database. Values are of the form
+  // `projects/<project>/instances/<instance>/databases/<database>`.
+  string name = 1;
+}
+
+// Enqueues the given DDL statements to be applied, in order but not
+// necessarily all at once, to the database schema at some point (or
+// points) in the future. The server checks that the statements
+// are executable (syntactically valid, name tables that exist, etc.)
+// before enqueueing them, but they may still fail upon
+// later execution (e.g., if a statement from another batch of
+// statements is applied first and it conflicts in some way, or if
+// there is some data-related problem like a `NULL` value in a column to
+// which `NOT NULL` would be added). If a statement fails, all
+// subsequent statements in the batch are automatically cancelled.
+//
+// Each batch of statements is assigned a name which can be used with
+// the [Operations][google.longrunning.Operations] API to monitor
+// progress. See the
+// [operation_id][google.spanner.admin.database.v1.UpdateDatabaseDdlRequest.operation_id] field for more
+// details.
+message UpdateDatabaseDdlRequest {
+  // Required. The database to update.
+  string database = 1;
+
+  // DDL statements to be applied to the database.
+  repeated string statements = 2;
+
+  // If empty, the new update request is assigned an
+  // automatically-generated operation ID. Otherwise, `operation_id`
+  // is used to construct the name of the resulting
+  // [Operation][google.longrunning.Operation].
+  //
+  // Specifying an explicit operation ID simplifies determining
+  // whether the statements were executed in the event that the
+  // [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl] call is replayed,
+  // or the return value is otherwise lost: the [database][google.spanner.admin.database.v1.UpdateDatabaseDdlRequest.database] and
+  // `operation_id` fields can be combined to form the
+  // [name][google.longrunning.Operation.name] of the resulting
+  // [longrunning.Operation][google.longrunning.Operation]: `<database>/operations/<operation_id>`.
+  //
+  // `operation_id` should be unique within the database, and must be
+  // a valid identifier: `[a-z][a-z0-9_]*`. Note that
+  // automatically-generated operation IDs always begin with an
+  // underscore. If the named operation already exists,
+  // [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl] returns
+  // `ALREADY_EXISTS`.
+  string operation_id = 3;
+}
+
+// Metadata type for the operation returned by
+// [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl].
+message UpdateDatabaseDdlMetadata {
+  // The database being modified.
+  string database = 1;
+
+  // For an update this list contains all the statements. For an
+  // individual statement, this list contains only that statement.
+  repeated string statements = 2;
+
+  // Reports the commit timestamps of all statements that have
+  // succeeded so far, where `commit_timestamps[i]` is the commit
+  // timestamp for the statement `statements[i]`.
+  repeated google.protobuf.Timestamp commit_timestamps = 3;
+}
+
+// The request for [DropDatabase][google.spanner.admin.database.v1.DatabaseAdmin.DropDatabase].
+message DropDatabaseRequest {
+  // Required. The database to be dropped.
+  string database = 1;
+}
+
+// The request for [GetDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabaseDdl].
+message GetDatabaseDdlRequest {
+  // Required. The database whose schema we wish to get.
+  string database = 1;
+}
+
+// The response for [GetDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabaseDdl].
+message GetDatabaseDdlResponse {
+  // A list of formatted DDL statements defining the schema of the database
+  // specified in the request.
+  repeated string statements = 1;
+}
diff --git a/spanner/google/cloud/spanner_v1/proto/spanner_instance_admin.proto b/spanner/google/cloud/spanner_v1/proto/spanner_instance_admin.proto
new file mode 100644
index 000000000000..e960e5428e3a
--- /dev/null
+++ b/spanner/google/cloud/spanner_v1/proto/spanner_instance_admin.proto
@@ -0,0 +1,475 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.admin.instance.v1;
+
+import "google/api/annotations.proto";
+import "google/iam/v1/iam_policy.proto";
+import "google/iam/v1/policy.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Spanner.Admin.Instance.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/admin/instance/v1;instance";
+option java_multiple_files = true;
+option java_outer_classname = "SpannerInstanceAdminProto";
+option java_package = "com.google.spanner.admin.instance.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\Admin\\Instance\\V1";
+
+
+// Cloud Spanner Instance Admin API
+//
+// The Cloud Spanner Instance Admin API can be used to create, delete,
+// modify and list instances. Instances are dedicated Cloud Spanner serving
+// and storage resources to be used by Cloud Spanner databases.
+//
+// Each instance has a "configuration", which dictates where the
+// serving resources for the Cloud Spanner instance are located (e.g.,
+// US-central, Europe). Configurations are created by Google based on
+// resource availability.
+//
+// Cloud Spanner billing is based on the instances that exist and their
+// sizes. After an instance exists, there are no additional
+// per-database or per-operation charges for use of the instance
+// (though there may be additional network bandwidth charges).
+// Instances offer isolation: problems with databases in one instance
+// will not affect other instances. However, within an instance
+// databases can affect each other. For example, if one database in an
+// instance receives a lot of requests and consumes most of the
+// instance resources, fewer resources are available for other
+// databases in that instance, and their performance may suffer.
+service InstanceAdmin {
+  // Lists the supported instance configurations for a given project.
+  rpc ListInstanceConfigs(ListInstanceConfigsRequest) returns (ListInstanceConfigsResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*}/instanceConfigs"
+    };
+  }
+
+  // Gets information about a particular instance configuration.
+  rpc GetInstanceConfig(GetInstanceConfigRequest) returns (InstanceConfig) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/instanceConfigs/*}"
+    };
+  }
+
+  // Lists all instances in the given project.
+  rpc ListInstances(ListInstancesRequest) returns (ListInstancesResponse) {
+    option (google.api.http) = {
+      get: "/v1/{parent=projects/*}/instances"
+    };
+  }
+
+  // Gets information about a particular instance.
+  rpc GetInstance(GetInstanceRequest) returns (Instance) {
+    option (google.api.http) = {
+      get: "/v1/{name=projects/*/instances/*}"
+    };
+  }
+
+  // Creates an instance and begins preparing it to begin serving. The
+  // returned [long-running operation][google.longrunning.Operation]
+  // can be used to track the progress of preparing the new
+  // instance. The instance name is assigned by the caller. If the
+  // named instance already exists, `CreateInstance` returns
+  // `ALREADY_EXISTS`.
+  //
+  // Immediately upon completion of this request:
+  //
+  //   * The instance is readable via the API, with all requested attributes
+  //     but no allocated resources. Its state is `CREATING`.
+  //
+  // Until completion of the returned operation:
+  //
+  //   * Cancelling the operation renders the instance immediately unreadable
+  //     via the API.
+  //   * The instance can be deleted.
+  //   * All other attempts to modify the instance are rejected.
+  //
+  // Upon completion of the returned operation:
+  //
+  //   * Billing for all successfully-allocated resources begins (some types
+  //     may have lower than the requested levels).
+  //   * Databases can be created in the instance.
+  //   * The instance's allocated resource levels are readable via the API.
+  //   * The instance's state becomes `READY`.
+  //
+  // The returned [long-running operation][google.longrunning.Operation] will
+  // have a name of the format `<instance_name>/operations/<operation_id>` and
+  // can be used to track creation of the instance.  The
+  // [metadata][google.longrunning.Operation.metadata] field type is
+  // [CreateInstanceMetadata][google.spanner.admin.instance.v1.CreateInstanceMetadata].
+  // The [response][google.longrunning.Operation.response] field type is
+  // [Instance][google.spanner.admin.instance.v1.Instance], if successful.
+  rpc CreateInstance(CreateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1/{parent=projects/*}/instances"
+      body: "*"
+    };
+  }
+
+  // Updates an instance, and begins allocating or releasing resources
+  // as requested. The returned [long-running
+  // operation][google.longrunning.Operation] can be used to track the
+  // progress of updating the instance. If the named instance does not
+  // exist, returns `NOT_FOUND`.
+  //
+  // Immediately upon completion of this request:
+  //
+  //   * For resource types for which a decrease in the instance's allocation
+  //     has been requested, billing is based on the newly-requested level.
+  //
+  // Until completion of the returned operation:
+  //
+  //   * Cancelling the operation sets its metadata's
+  //     [cancel_time][google.spanner.admin.instance.v1.UpdateInstanceMetadata.cancel_time], and begins
+  //     restoring resources to their pre-request values. The operation
+  //     is guaranteed to succeed at undoing all resource changes,
+  //     after which point it terminates with a `CANCELLED` status.
+  //   * All other attempts to modify the instance are rejected.
+  //   * Reading the instance via the API continues to give the pre-request
+  //     resource levels.
+  //
+  // Upon completion of the returned operation:
+  //
+  //   * Billing begins for all successfully-allocated resources (some types
+  //     may have lower than the requested levels).
+  //   * All newly-reserved resources are available for serving the instance's
+  //     tables.
+  //   * The instance's new resource levels are readable via the API.
+  //
+  // The returned [long-running operation][google.longrunning.Operation] will
+  // have a name of the format `<instance_name>/operations/<operation_id>` and
+  // can be used to track the instance modification.  The
+  // [metadata][google.longrunning.Operation.metadata] field type is
+  // [UpdateInstanceMetadata][google.spanner.admin.instance.v1.UpdateInstanceMetadata].
+  // The [response][google.longrunning.Operation.response] field type is
+  // [Instance][google.spanner.admin.instance.v1.Instance], if successful.
+  //
+  // Authorization requires `spanner.instances.update` permission on
+  // resource [name][google.spanner.admin.instance.v1.Instance.name].
+  rpc UpdateInstance(UpdateInstanceRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      patch: "/v1/{instance.name=projects/*/instances/*}"
+      body: "*"
+    };
+  }
+
+  // Deletes an instance.
+  //
+  // Immediately upon completion of the request:
+  //
+  //   * Billing ceases for all of the instance's reserved resources.
+  //
+  // Soon afterward:
+  //
+  //   * The instance and *all of its databases* immediately and
+  //     irrevocably disappear from the API. All data in the databases
+  //     is permanently deleted.
+  rpc DeleteInstance(DeleteInstanceRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1/{name=projects/*/instances/*}"
+    };
+  }
+
+  // Sets the access control policy on an instance resource. Replaces any
+  // existing policy.
+  //
+  // Authorization requires `spanner.instances.setIamPolicy` on
+  // [resource][google.iam.v1.SetIamPolicyRequest.resource].
+  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*}:setIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Gets the access control policy for an instance resource. Returns an empty
+  // policy if an instance exists but does not have a policy set.
+  //
+  // Authorization requires `spanner.instances.getIamPolicy` on
+  // [resource][google.iam.v1.GetIamPolicyRequest.resource].
+  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*}:getIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Returns permissions that the caller has on the specified instance resource.
+  //
+  // Attempting this RPC on a non-existent Cloud Spanner instance resource will
+  // result in a NOT_FOUND error if the user has `spanner.instances.list`
+  // permission on the containing Google Cloud Project. Otherwise returns an
+  // empty set of permissions.
+  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) {
+    option (google.api.http) = {
+      post: "/v1/{resource=projects/*/instances/*}:testIamPermissions"
+      body: "*"
+    };
+  }
+}
+
+// A possible configuration for a Cloud Spanner instance. Configurations
+// define the geographic placement of nodes and their replication.
+message InstanceConfig {
+  // A unique identifier for the instance configuration.  Values
+  // are of the form
+  // `projects/<project>/instanceConfigs/[a-z][-a-z0-9]*`
+  string name = 1;
+
+  // The name of this instance configuration as it appears in UIs.
+  string display_name = 2;
+}
+
+// An isolated set of Cloud Spanner resources on which databases can be hosted.
+message Instance {
+  // Indicates the current state of the instance.
+  enum State {
+    // Not specified.
+    STATE_UNSPECIFIED = 0;
+
+    // The instance is still being created. Resources may not be
+    // available yet, and operations such as database creation may not
+    // work.
+    CREATING = 1;
+
+    // The instance is fully created and ready to do work such as
+    // creating databases.
+    READY = 2;
+  }
+
+  // Required. A unique identifier for the instance, which cannot be changed
+  // after the instance is created. Values are of the form
+  // `projects/<project>/instances/[a-z][-a-z0-9]*[a-z0-9]`. The final
+  // segment of the name must be between 6 and 30 characters in length.
+  string name = 1;
+
+  // Required. The name of the instance's configuration. Values are of the form
+  // `projects/<project>/instanceConfigs/<configuration>`. See
+  // also [InstanceConfig][google.spanner.admin.instance.v1.InstanceConfig] and
+  // [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs].
+  string config = 2;
+
+  // Required. The descriptive name for this instance as it appears in UIs.
+  // Must be unique per project and between 4 and 30 characters in length.
+  string display_name = 3;
+
+  // Required. The number of nodes allocated to this instance. This may be zero
+  // in API responses for instances that are not yet in state `READY`.
+  //
+  // See [the documentation](https://cloud.google.com/spanner/docs/instances#node_count)
+  // for more information about nodes.
+  int32 node_count = 5;
+
+  // Output only. The current instance state. For
+  // [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance], the state must be
+  // either omitted or set to `CREATING`. For
+  // [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance], the state must be
+  // either omitted or set to `READY`.
+  State state = 6;
+
+  // Cloud Labels are a flexible and lightweight mechanism for organizing cloud
+  // resources into groups that reflect a customer's organizational needs and
+  // deployment strategies. Cloud Labels can be used to filter collections of
+  // resources. They can be used to control how resource metrics are aggregated.
+  // And they can be used as arguments to policy management rules (e.g. route,
+  // firewall, load balancing, etc.).
+  //
+  //  * Label keys must be between 1 and 63 characters long and must conform to
+  //    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+  //  * Label values must be between 0 and 63 characters long and must conform
+  //    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+  //  * No more than 64 labels can be associated with a given resource.
+  //
+  // See https://goo.gl/xmQnxf for more information on and examples of labels.
+  //
+  // If you plan to use labels in your own code, please note that additional
+  // characters may be allowed in the future. And so you are advised to use an
+  // internal label representation, such as JSON, which doesn't rely upon
+  // specific characters being disallowed.  For example, representing labels
+  // as the string:  name + "_" + value  would prove problematic if we were to
+  // allow "_" in a future release.
+  map<string, string> labels = 7;
+}
+
+// The request for [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs].
+message ListInstanceConfigsRequest {
+  // Required. The name of the project for which a list of supported instance
+  // configurations is requested. Values are of the form
+  // `projects/<project>`.
+  string parent = 1;
+
+  // Number of instance configurations to be returned in the response. If 0 or
+  // less, defaults to the server's maximum allowed page size.
+  int32 page_size = 2;
+
+  // If non-empty, `page_token` should contain a
+  // [next_page_token][google.spanner.admin.instance.v1.ListInstanceConfigsResponse.next_page_token]
+  // from a previous [ListInstanceConfigsResponse][google.spanner.admin.instance.v1.ListInstanceConfigsResponse].
+  string page_token = 3;
+}
+
+// The response for [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs].
+message ListInstanceConfigsResponse {
+  // The list of requested instance configurations.
+  repeated InstanceConfig instance_configs = 1;
+
+  // `next_page_token` can be sent in a subsequent
+  // [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs] call to
+  // fetch more of the matching instance configurations.
+  string next_page_token = 2;
+}
+
+// The request for
+// [GetInstanceConfigRequest][google.spanner.admin.instance.v1.InstanceAdmin.GetInstanceConfig].
+message GetInstanceConfigRequest {
+  // Required. The name of the requested instance configuration. Values are of
+  // the form `projects/<project>/instanceConfigs/<config>`.
+  string name = 1;
+}
+
+// The request for [GetInstance][google.spanner.admin.instance.v1.InstanceAdmin.GetInstance].
+message GetInstanceRequest {
+  // Required. The name of the requested instance. Values are of the form
+  // `projects/<project>/instances/<instance>`.
+  string name = 1;
+}
+
+// The request for [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance].
+message CreateInstanceRequest {
+  // Required. The name of the project in which to create the instance. Values
+  // are of the form `projects/<project>`.
+  string parent = 1;
+
+  // Required. The ID of the instance to create.  Valid identifiers are of the
+  // form `[a-z][-a-z0-9]*[a-z0-9]` and must be between 6 and 30 characters in
+  // length.
+  string instance_id = 2;
+
+  // Required. The instance to create.  The name may be omitted, but if
+  // specified must be `<parent>/instances/<instance_id>`.
+  Instance instance = 3;
+}
+
+// The request for [ListInstances][google.spanner.admin.instance.v1.InstanceAdmin.ListInstances].
+message ListInstancesRequest {
+  // Required. The name of the project for which a list of instances is
+  // requested. Values are of the form `projects/<project>`.
+  string parent = 1;
+
+  // Number of instances to be returned in the response. If 0 or less, defaults
+  // to the server's maximum allowed page size.
+  int32 page_size = 2;
+
+  // If non-empty, `page_token` should contain a
+  // [next_page_token][google.spanner.admin.instance.v1.ListInstancesResponse.next_page_token] from a
+  // previous [ListInstancesResponse][google.spanner.admin.instance.v1.ListInstancesResponse].
+  string page_token = 3;
+
+  // An expression for filtering the results of the request. Filter rules are
+  // case insensitive. The fields eligible for filtering are:
+  //
+  //   * `name`
+  //   * `display_name`
+  //   * `labels.key` where key is the name of a label
+  //
+  // Some examples of using filters are:
+  //
+  //   * `name:*` --> The instance has a name.
+  //   * `name:Howl` --> The instance's name contains the string "howl".
+  //   * `name:HOWL` --> Equivalent to above.
+  //   * `NAME:howl` --> Equivalent to above.
+  //   * `labels.env:*` --> The instance has the label "env".
+  //   * `labels.env:dev` --> The instance has the label "env" and the value of
+  //                        the label contains the string "dev".
+  //   * `name:howl labels.env:dev` --> The instance's name contains "howl" and
+  //                                  it has the label "env" with its value
+  //                                  containing "dev".
+  string filter = 4;
+}
+
+// The response for [ListInstances][google.spanner.admin.instance.v1.InstanceAdmin.ListInstances].
+message ListInstancesResponse {
+  // The list of requested instances.
+  repeated Instance instances = 1;
+
+  // `next_page_token` can be sent in a subsequent
+  // [ListInstances][google.spanner.admin.instance.v1.InstanceAdmin.ListInstances] call to fetch more
+  // of the matching instances.
+  string next_page_token = 2;
+}
+
+// The request for [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance].
+message UpdateInstanceRequest {
+  // Required. The instance to update, which must always include the instance
+  // name.  Otherwise, only fields mentioned in [][google.spanner.admin.instance.v1.UpdateInstanceRequest.field_mask] need be included.
+  Instance instance = 1;
+
+  // Required. A mask specifying which fields in [][google.spanner.admin.instance.v1.UpdateInstanceRequest.instance] should be updated.
+  // The field mask must always be specified; this prevents any future fields in
+  // [][google.spanner.admin.instance.v1.Instance] from being erased accidentally by clients that do not know
+  // about them.
+  google.protobuf.FieldMask field_mask = 2;
+}
+
+// The request for [DeleteInstance][google.spanner.admin.instance.v1.InstanceAdmin.DeleteInstance].
+message DeleteInstanceRequest {
+  // Required. The name of the instance to be deleted. Values are of the form
+  // `projects/<project>/instances/<instance>`
+  string name = 1;
+}
+
+// Metadata type for the operation returned by
+// [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance].
+message CreateInstanceMetadata {
+  // The instance being created.
+  Instance instance = 1;
+
+  // The time at which the
+  // [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance] request was
+  // received.
+  google.protobuf.Timestamp start_time = 2;
+
+  // The time at which this operation was cancelled. If set, this operation is
+  // in the process of undoing itself (which is guaranteed to succeed) and
+  // cannot be cancelled again.
+  google.protobuf.Timestamp cancel_time = 3;
+
+  // The time at which this operation failed or was completed successfully.
+  google.protobuf.Timestamp end_time = 4;
+}
+
+// Metadata type for the operation returned by
+// [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance].
+message UpdateInstanceMetadata {
+  // The desired end state of the update.
+  Instance instance = 1;
+
+  // The time at which [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance]
+  // request was received.
+  google.protobuf.Timestamp start_time = 2;
+
+  // The time at which this operation was cancelled. If set, this operation is
+  // in the process of undoing itself (which is guaranteed to succeed) and
+  // cannot be cancelled again.
+  google.protobuf.Timestamp cancel_time = 3;
+
+  // The time at which this operation failed or was completed successfully.
+  google.protobuf.Timestamp end_time = 4;
+}
diff --git a/spanner/google/cloud/spanner_v1/proto/transaction.proto b/spanner/google/cloud/spanner_v1/proto/transaction.proto
new file mode 100644
index 000000000000..e7fafc0e7655
--- /dev/null
+++ b/spanner/google/cloud/spanner_v1/proto/transaction.proto
@@ -0,0 +1,456 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.v1;
+
+import "google/api/annotations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Spanner.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner";
+option java_multiple_files = true;
+option java_outer_classname = "TransactionProto";
+option java_package = "com.google.spanner.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\V1";
+
+
+// # Transactions
+//
+//
+// Each session can have at most one active transaction at a time. After the
+// active transaction is completed, the session can immediately be
+// re-used for the next transaction. It is not necessary to create a
+// new session for each transaction.
+//
+// # Transaction Modes
+//
+// Cloud Spanner supports three transaction modes:
+//
+//   1. Locking read-write. This type of transaction is the only way
+//      to write data into Cloud Spanner. These transactions rely on
+//      pessimistic locking and, if necessary, two-phase commit.
+//      Locking read-write transactions may abort, requiring the
+//      application to retry.
+//
+//   2. Snapshot read-only. This transaction type provides guaranteed
+//      consistency across several reads, but does not allow
+//      writes. Snapshot read-only transactions can be configured to
+//      read at timestamps in the past. Snapshot read-only
+//      transactions do not need to be committed.
+//
+//   3. Partitioned DML. This type of transaction is used to execute
+//      a single Partitioned DML statement. Partitioned DML partitions
+//      the key space and runs the DML statement over each partition
+//      in parallel using separate, internal transactions that commit
+//      independently. Partitioned DML transactions do not need to be
+//      committed.
+//
+// For transactions that only read, snapshot read-only transactions
+// provide simpler semantics and are almost always faster. In
+// particular, read-only transactions do not take locks, so they do
+// not conflict with read-write transactions. As a consequence of not
+// taking locks, they also do not abort, so retry loops are not needed.
+//
+// Transactions may only read/write data in a single database. They
+// may, however, read/write data in different tables within that
+// database.
+//
+// ## Locking Read-Write Transactions
+//
+// Locking transactions may be used to atomically read-modify-write
+// data anywhere in a database. This type of transaction is externally
+// consistent.
+//
+// Clients should attempt to minimize the amount of time a transaction
+// is active. Faster transactions commit with higher probability
+// and cause less contention. Cloud Spanner attempts to keep read locks
+// active as long as the transaction continues to do reads, and the
+// transaction has not been terminated by
+// [Commit][google.spanner.v1.Spanner.Commit] or
+// [Rollback][google.spanner.v1.Spanner.Rollback].  Long periods of
+// inactivity at the client may cause Cloud Spanner to release a
+// transaction's locks and abort it.
+//
+// Conceptually, a read-write transaction consists of zero or more
+// reads or SQL statements followed by
+// [Commit][google.spanner.v1.Spanner.Commit]. At any time before
+// [Commit][google.spanner.v1.Spanner.Commit], the client can send a
+// [Rollback][google.spanner.v1.Spanner.Rollback] request to abort the
+// transaction.
+//
+// ### Semantics
+//
+// Cloud Spanner can commit the transaction if all read locks it acquired
+// are still valid at commit time, and it is able to acquire write
+// locks for all writes. Cloud Spanner can abort the transaction for any
+// reason. If a commit attempt returns `ABORTED`, Cloud Spanner guarantees
+// that the transaction has not modified any user data in Cloud Spanner.
+//
+// Unless the transaction commits, Cloud Spanner makes no guarantees about
+// how long the transaction's locks were held for. It is an error to
+// use Cloud Spanner locks for any sort of mutual exclusion other than
+// between Cloud Spanner transactions themselves.
+//
+// ### Retrying Aborted Transactions
+//
+// When a transaction aborts, the application can choose to retry the
+// whole transaction again. To maximize the chances of successfully
+// committing the retry, the client should execute the retry in the
+// same session as the original attempt. The original session's lock
+// priority increases with each consecutive abort, meaning that each
+// attempt has a slightly better chance of success than the previous.
+//
+// Under some circumstances (e.g., many transactions attempting to
+// modify the same row(s)), a transaction can abort many times in a
+// short period before successfully committing. Thus, it is not a good
+// idea to cap the number of retries a transaction can attempt;
+// instead, it is better to limit the total amount of wall time spent
+// retrying.
+//
+// ### Idle Transactions
+//
+// A transaction is considered idle if it has no outstanding reads or
+// SQL queries and has not started a read or SQL query within the last 10
+// seconds. Idle transactions can be aborted by Cloud Spanner so that they
+// don't hold on to locks indefinitely. In that case, the commit will
+// fail with error `ABORTED`.
+//
+// If this behavior is undesirable, periodically executing a simple
+// SQL query in the transaction (e.g., `SELECT 1`) prevents the
+// transaction from becoming idle.
+//
+// ## Snapshot Read-Only Transactions
+//
+// Snapshot read-only transactions provides a simpler method than
+// locking read-write transactions for doing several consistent
+// reads. However, this type of transaction does not support writes.
+//
+// Snapshot transactions do not take locks. Instead, they work by
+// choosing a Cloud Spanner timestamp, then executing all reads at that
+// timestamp. Since they do not acquire locks, they do not block
+// concurrent read-write transactions.
+//
+// Unlike locking read-write transactions, snapshot read-only
+// transactions never abort. They can fail if the chosen read
+// timestamp is garbage collected; however, the default garbage
+// collection policy is generous enough that most applications do not
+// need to worry about this in practice.
+//
+// Snapshot read-only transactions do not need to call
+// [Commit][google.spanner.v1.Spanner.Commit] or
+// [Rollback][google.spanner.v1.Spanner.Rollback] (and in fact are not
+// permitted to do so).
+//
+// To execute a snapshot transaction, the client specifies a timestamp
+// bound, which tells Cloud Spanner how to choose a read timestamp.
+//
+// The types of timestamp bound are:
+//
+//   - Strong (the default).
+//   - Bounded staleness.
+//   - Exact staleness.
+//
+// If the Cloud Spanner database to be read is geographically distributed,
+// stale read-only transactions can execute more quickly than strong
+// or read-write transaction, because they are able to execute far
+// from the leader replica.
+//
+// Each type of timestamp bound is discussed in detail below.
+//
+// ### Strong
+//
+// Strong reads are guaranteed to see the effects of all transactions
+// that have committed before the start of the read. Furthermore, all
+// rows yielded by a single read are consistent with each other -- if
+// any part of the read observes a transaction, all parts of the read
+// see the transaction.
+//
+// Strong reads are not repeatable: two consecutive strong read-only
+// transactions might return inconsistent results if there are
+// concurrent writes. If consistency across reads is required, the
+// reads should be executed within a transaction or at an exact read
+// timestamp.
+//
+// See [TransactionOptions.ReadOnly.strong][google.spanner.v1.TransactionOptions.ReadOnly.strong].
+//
+// ### Exact Staleness
+//
+// These timestamp bounds execute reads at a user-specified
+// timestamp. Reads at a timestamp are guaranteed to see a consistent
+// prefix of the global transaction history: they observe
+// modifications done by all transactions with a commit timestamp <=
+// the read timestamp, and observe none of the modifications done by
+// transactions with a larger commit timestamp. They will block until
+// all conflicting transactions that may be assigned commit timestamps
+// <= the read timestamp have finished.
+//
+// The timestamp can either be expressed as an absolute Cloud Spanner commit
+// timestamp or a staleness relative to the current time.
+//
+// These modes do not require a "negotiation phase" to pick a
+// timestamp. As a result, they execute slightly faster than the
+// equivalent boundedly stale concurrency modes. On the other hand,
+// boundedly stale reads usually return fresher results.
+//
+// See [TransactionOptions.ReadOnly.read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.read_timestamp] and
+// [TransactionOptions.ReadOnly.exact_staleness][google.spanner.v1.TransactionOptions.ReadOnly.exact_staleness].
+//
+// ### Bounded Staleness
+//
+// Bounded staleness modes allow Cloud Spanner to pick the read timestamp,
+// subject to a user-provided staleness bound. Cloud Spanner chooses the
+// newest timestamp within the staleness bound that allows execution
+// of the reads at the closest available replica without blocking.
+//
+// All rows yielded are consistent with each other -- if any part of
+// the read observes a transaction, all parts of the read see the
+// transaction. Boundedly stale reads are not repeatable: two stale
+// reads, even if they use the same staleness bound, can execute at
+// different timestamps and thus return inconsistent results.
+//
+// Boundedly stale reads execute in two phases: the first phase
+// negotiates a timestamp among all replicas needed to serve the
+// read. In the second phase, reads are executed at the negotiated
+// timestamp.
+//
+// As a result of the two phase execution, bounded staleness reads are
+// usually a little slower than comparable exact staleness
+// reads. However, they are typically able to return fresher
+// results, and are more likely to execute at the closest replica.
+//
+// Because the timestamp negotiation requires up-front knowledge of
+// which rows will be read, it can only be used with single-use
+// read-only transactions.
+//
+// See [TransactionOptions.ReadOnly.max_staleness][google.spanner.v1.TransactionOptions.ReadOnly.max_staleness] and
+// [TransactionOptions.ReadOnly.min_read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.min_read_timestamp].
+//
+// ### Old Read Timestamps and Garbage Collection
+//
+// Cloud Spanner continuously garbage collects deleted and overwritten data
+// in the background to reclaim storage space. This process is known
+// as "version GC". By default, version GC reclaims versions after they
+// are one hour old. Because of this, Cloud Spanner cannot perform reads
+// at read timestamps more than one hour in the past. This
+// restriction also applies to in-progress reads and/or SQL queries whose
+// timestamp become too old while executing. Reads and SQL queries with
+// too-old read timestamps fail with the error `FAILED_PRECONDITION`.
+//
+// ## Partitioned DML Transactions
+//
+// Partitioned DML transactions are used to execute DML statements with a
+// different execution strategy that provides different, and often better,
+// scalability properties for large, table-wide operations than DML in a
+// ReadWrite transaction. Smaller scoped statements, such as an OLTP workload,
+// should prefer using ReadWrite transactions.
+//
+// Partitioned DML partitions the keyspace and runs the DML statement on each
+// partition in separate, internal transactions. These transactions commit
+// automatically when complete, and run independently from one another.
+//
+// To reduce lock contention, this execution strategy only acquires read locks
+// on rows that match the WHERE clause of the statement. Additionally, the
+// smaller per-partition transactions hold locks for less time.
+//
+// That said, Partitioned DML is not a drop-in replacement for standard DML used
+// in ReadWrite transactions.
+//
+//  - The DML statement must be fully-partitionable. Specifically, the statement
+//    must be expressible as the union of many statements which each access only
+//    a single row of the table.
+//
+//  - The statement is not applied atomically to all rows of the table. Rather,
+//    the statement is applied atomically to partitions of the table, in
+//    independent transactions. Secondary index rows are updated atomically
+//    with the base table rows.
+//
+//  - Partitioned DML does not guarantee exactly-once execution semantics
+//    against a partition. The statement will be applied at least once to each
+//    partition. It is strongly recommended that the DML statement should be
+//    idempotent to avoid unexpected results. For instance, it is potentially
+//    dangerous to run a statement such as
+//    `UPDATE table SET column = column + 1` as it could be run multiple times
+//    against some rows.
+//
+//  - The partitions are committed automatically - there is no support for
+//    Commit or Rollback. If the call returns an error, or if the client issuing
+//    the ExecuteSql call dies, it is possible that some rows had the statement
+//    executed on them successfully. It is also possible that statement was
+//    never executed against other rows.
+//
+//  - Partitioned DML transactions may only contain the execution of a single
+//    DML statement via ExecuteSql or ExecuteStreamingSql.
+//
+//  - If any error is encountered during the execution of the partitioned DML
+//    operation (for instance, a UNIQUE INDEX violation, division by zero, or a
+//    value that cannot be stored due to schema constraints), then the
+//    operation is stopped at that point and an error is returned. It is
+//    possible that at this point, some partitions have been committed (or even
+//    committed multiple times), and other partitions have not been run at all.
+//
+// Given the above, Partitioned DML is good fit for large, database-wide,
+// operations that are idempotent, such as deleting old rows from a very large
+// table.
+message TransactionOptions {
+  // Message type to initiate a read-write transaction. Currently this
+  // transaction type has no options.
+  message ReadWrite {
+
+  }
+
+  // Message type to initiate a Partitioned DML transaction.
+  message PartitionedDml {
+
+  }
+
+  // Message type to initiate a read-only transaction.
+  message ReadOnly {
+    // How to choose the timestamp for the read-only transaction.
+    oneof timestamp_bound {
+      // Read at a timestamp where all previously committed transactions
+      // are visible.
+      bool strong = 1;
+
+      // Executes all reads at a timestamp >= `min_read_timestamp`.
+      //
+      // This is useful for requesting fresher data than some previous
+      // read, or data that is fresh enough to observe the effects of some
+      // previously committed transaction whose timestamp is known.
+      //
+      // Note that this option can only be used in single-use transactions.
+      //
+      // A timestamp in RFC3339 UTC \"Zulu\" format, accurate to nanoseconds.
+      // Example: `"2014-10-02T15:01:23.045123456Z"`.
+      google.protobuf.Timestamp min_read_timestamp = 2;
+
+      // Read data at a timestamp >= `NOW - max_staleness`
+      // seconds. Guarantees that all writes that have committed more
+      // than the specified number of seconds ago are visible. Because
+      // Cloud Spanner chooses the exact timestamp, this mode works even if
+      // the client's local clock is substantially skewed from Cloud Spanner
+      // commit timestamps.
+      //
+      // Useful for reading the freshest data available at a nearby
+      // replica, while bounding the possible staleness if the local
+      // replica has fallen behind.
+      //
+      // Note that this option can only be used in single-use
+      // transactions.
+      google.protobuf.Duration max_staleness = 3;
+
+      // Executes all reads at the given timestamp. Unlike other modes,
+      // reads at a specific timestamp are repeatable; the same read at
+      // the same timestamp always returns the same data. If the
+      // timestamp is in the future, the read will block until the
+      // specified timestamp, modulo the read's deadline.
+      //
+      // Useful for large scale consistent reads such as mapreduces, or
+      // for coordinating many reads against a consistent snapshot of the
+      // data.
+      //
+      // A timestamp in RFC3339 UTC \"Zulu\" format, accurate to nanoseconds.
+      // Example: `"2014-10-02T15:01:23.045123456Z"`.
+      google.protobuf.Timestamp read_timestamp = 4;
+
+      // Executes all reads at a timestamp that is `exact_staleness`
+      // old. The timestamp is chosen soon after the read is started.
+      //
+      // Guarantees that all writes that have committed more than the
+      // specified number of seconds ago are visible. Because Cloud Spanner
+      // chooses the exact timestamp, this mode works even if the client's
+      // local clock is substantially skewed from Cloud Spanner commit
+      // timestamps.
+      //
+      // Useful for reading at nearby replicas without the distributed
+      // timestamp negotiation overhead of `max_staleness`.
+      google.protobuf.Duration exact_staleness = 5;
+    }
+
+    // If true, the Cloud Spanner-selected read timestamp is included in
+    // the [Transaction][google.spanner.v1.Transaction] message that describes the transaction.
+    bool return_read_timestamp = 6;
+  }
+
+  // Required. The type of transaction.
+  oneof mode {
+    // Transaction may write.
+    //
+    // Authorization to begin a read-write transaction requires
+    // `spanner.databases.beginOrRollbackReadWriteTransaction` permission
+    // on the `session` resource.
+    ReadWrite read_write = 1;
+
+    // Partitioned DML transaction.
+    //
+    // Authorization to begin a Partitioned DML transaction requires
+    // `spanner.databases.beginPartitionedDmlTransaction` permission
+    // on the `session` resource.
+    PartitionedDml partitioned_dml = 3;
+
+    // Transaction will not write.
+    //
+    // Authorization to begin a read-only transaction requires
+    // `spanner.databases.beginReadOnlyTransaction` permission
+    // on the `session` resource.
+    ReadOnly read_only = 2;
+  }
+}
+
+// A transaction.
+message Transaction {
+  // `id` may be used to identify the transaction in subsequent
+  // [Read][google.spanner.v1.Spanner.Read],
+  // [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql],
+  // [Commit][google.spanner.v1.Spanner.Commit], or
+  // [Rollback][google.spanner.v1.Spanner.Rollback] calls.
+  //
+  // Single-use read-only transactions do not have IDs, because
+  // single-use transactions do not support multiple requests.
+  bytes id = 1;
+
+  // For snapshot read-only transactions, the read timestamp chosen
+  // for the transaction. Not returned by default: see
+  // [TransactionOptions.ReadOnly.return_read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.return_read_timestamp].
+  //
+  // A timestamp in RFC3339 UTC \"Zulu\" format, accurate to nanoseconds.
+  // Example: `"2014-10-02T15:01:23.045123456Z"`.
+  google.protobuf.Timestamp read_timestamp = 2;
+}
+
+// This message is used to select the transaction in which a
+// [Read][google.spanner.v1.Spanner.Read] or
+// [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] call runs.
+//
+// See [TransactionOptions][google.spanner.v1.TransactionOptions] for more information about transactions.
+message TransactionSelector {
+  // If no fields are set, the default is a single use transaction
+  // with strong concurrency.
+  oneof selector {
+    // Execute the read or SQL query in a temporary transaction.
+    // This is the most efficient way to execute a transaction that
+    // consists of a single SQL query.
+    TransactionOptions single_use = 1;
+
+    // Execute the read or SQL query in a previously-started transaction.
+    bytes id = 2;
+
+    // Begin a new transaction and execute this read or SQL query in
+    // it. The transaction ID of the new transaction is returned in
+    // [ResultSetMetadata.transaction][google.spanner.v1.ResultSetMetadata.transaction], which is a [Transaction][google.spanner.v1.Transaction].
+    TransactionOptions begin = 3;
+  }
+}
diff --git a/spanner/google/cloud/spanner_v1/proto/type.proto b/spanner/google/cloud/spanner_v1/proto/type.proto
new file mode 100644
index 000000000000..de5203dd5f9f
--- /dev/null
+++ b/spanner/google/cloud/spanner_v1/proto/type.proto
@@ -0,0 +1,118 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package google.spanner.v1;
+
+import "google/api/annotations.proto";
+
+option csharp_namespace = "Google.Cloud.Spanner.V1";
+option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner";
+option java_multiple_files = true;
+option java_outer_classname = "TypeProto";
+option java_package = "com.google.spanner.v1";
+option php_namespace = "Google\\Cloud\\Spanner\\V1";
+
+
+// `Type` indicates the type of a Cloud Spanner value, as might be stored in a
+// table cell or returned from an SQL query.
+message Type {
+  // Required. The [TypeCode][google.spanner.v1.TypeCode] for this type.
+  TypeCode code = 1;
+
+  // If [code][google.spanner.v1.Type.code] == [ARRAY][google.spanner.v1.TypeCode.ARRAY], then `array_element_type`
+  // is the type of the array elements.
+  Type array_element_type = 2;
+
+  // If [code][google.spanner.v1.Type.code] == [STRUCT][google.spanner.v1.TypeCode.STRUCT], then `struct_type`
+  // provides type information for the struct's fields.
+  StructType struct_type = 3;
+}
+
+// `StructType` defines the fields of a [STRUCT][google.spanner.v1.TypeCode.STRUCT] type.
+message StructType {
+  // Message representing a single field of a struct.
+  message Field {
+    // The name of the field. For reads, this is the column name. For
+    // SQL queries, it is the column alias (e.g., `"Word"` in the
+    // query `"SELECT 'hello' AS Word"`), or the column name (e.g.,
+    // `"ColName"` in the query `"SELECT ColName FROM Table"`). Some
+    // columns might have an empty name (e.g., !"SELECT
+    // UPPER(ColName)"`). Note that a query result can contain
+    // multiple fields with the same name.
+    string name = 1;
+
+    // The type of the field.
+    Type type = 2;
+  }
+
+  // The list of fields that make up this struct. Order is
+  // significant, because values of this struct type are represented as
+  // lists, where the order of field values matches the order of
+  // fields in the [StructType][google.spanner.v1.StructType]. In turn, the order of fields
+  // matches the order of columns in a read request, or the order of
+  // fields in the `SELECT` clause of a query.
+  repeated Field fields = 1;
+}
+
+// `TypeCode` is used as part of [Type][google.spanner.v1.Type] to
+// indicate the type of a Cloud Spanner value.
+//
+// Each legal value of a type can be encoded to or decoded from a JSON
+// value, using the encodings described below. All Cloud Spanner values can
+// be `null`, regardless of type; `null`s are always encoded as a JSON
+// `null`.
+enum TypeCode {
+  // Not specified.
+  TYPE_CODE_UNSPECIFIED = 0;
+
+  // Encoded as JSON `true` or `false`.
+  BOOL = 1;
+
+  // Encoded as `string`, in decimal format.
+  INT64 = 2;
+
+  // Encoded as `number`, or the strings `"NaN"`, `"Infinity"`, or
+  // `"-Infinity"`.
+  FLOAT64 = 3;
+
+  // Encoded as `string` in RFC 3339 timestamp format. The time zone
+  // must be present, and must be `"Z"`.
+  //
+  // If the schema has the column option
+  // `allow_commit_timestamp=true`, the placeholder string
+  // `"spanner.commit_timestamp()"` can be used to instruct the system
+  // to insert the commit timestamp associated with the transaction
+  // commit.
+  TIMESTAMP = 4;
+
+  // Encoded as `string` in RFC 3339 date format.
+  DATE = 5;
+
+  // Encoded as `string`.
+  STRING = 6;
+
+  // Encoded as a base64-encoded `string`, as described in RFC 4648,
+  // section 4.
+  BYTES = 7;
+
+  // Encoded as `list`, where the list elements are represented
+  // according to [array_element_type][google.spanner.v1.Type.array_element_type].
+  ARRAY = 8;
+
+  // Encoded as `list`, where list element `i` is represented according
+  // to [struct_type.fields[i]][google.spanner.v1.StructType.fields].
+  STRUCT = 9;
+}
diff --git a/spanner/synth.metadata b/spanner/synth.metadata
index 266273ddbadc..245bb1084c87 100644
--- a/spanner/synth.metadata
+++ b/spanner/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:27:27.959942Z",
+  "updateTime": "2019-01-24T17:32:00.257867Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/spanner/synth.py b/spanner/synth.py
index 7067ede55bc7..36bf9bccc75e 100644
--- a/spanner/synth.py
+++ b/spanner/synth.py
@@ -27,6 +27,7 @@
     "v1",
     config_path="/google/spanner/artman_spanner.yaml",
     artman_output_name="spanner-v1",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/spanner_v1/proto")
@@ -72,6 +73,7 @@
     "v1",
     config_path="/google/spanner/admin/instance" "/artman_spanner_admin_instance.yaml",
     artman_output_name="spanner-admin-instance-v1",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/spanner_admin_instance_v1/gapic")
@@ -105,6 +107,7 @@
     "v1",
     config_path="/google/spanner/admin/database" "/artman_spanner_admin_database.yaml",
     artman_output_name="spanner-admin-database-v1",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/spanner_admin_database_v1/gapic")
diff --git a/speech/google/cloud/speech_v1/proto/cloud_speech.proto b/speech/google/cloud/speech_v1/proto/cloud_speech.proto
new file mode 100644
index 000000000000..53283d3b7d33
--- /dev/null
+++ b/speech/google/cloud/speech_v1/proto/cloud_speech.proto
@@ -0,0 +1,765 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.speech.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1;speech";
+option java_multiple_files = true;
+option java_outer_classname = "SpeechProto";
+option java_package = "com.google.cloud.speech.v1p1beta1";
+
+
+// Service that implements Google Cloud Speech API.
+service Speech {
+  // Performs synchronous speech recognition: receive results after all audio
+  // has been sent and processed.
+  rpc Recognize(RecognizeRequest) returns (RecognizeResponse) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/speech:recognize"
+      body: "*"
+    };
+  }
+
+  // Performs asynchronous speech recognition: receive results via the
+  // google.longrunning.Operations interface. Returns either an
+  // `Operation.error` or an `Operation.response` which contains
+  // a `LongRunningRecognizeResponse` message.
+  rpc LongRunningRecognize(LongRunningRecognizeRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/speech:longrunningrecognize"
+      body: "*"
+    };
+  }
+
+  // Performs bidirectional streaming speech recognition: receive results while
+  // sending audio. This method is only available via the gRPC API (not REST).
+  rpc StreamingRecognize(stream StreamingRecognizeRequest) returns (stream StreamingRecognizeResponse) {
+  }
+}
+
+// The top-level message sent by the client for the `Recognize` method.
+message RecognizeRequest {
+  // *Required* Provides information to the recognizer that specifies how to
+  // process the request.
+  RecognitionConfig config = 1;
+
+  // *Required* The audio data to be recognized.
+  RecognitionAudio audio = 2;
+}
+
+// The top-level message sent by the client for the `LongRunningRecognize`
+// method.
+message LongRunningRecognizeRequest {
+  // *Required* Provides information to the recognizer that specifies how to
+  // process the request.
+  RecognitionConfig config = 1;
+
+  // *Required* The audio data to be recognized.
+  RecognitionAudio audio = 2;
+}
+
+// The top-level message sent by the client for the `StreamingRecognize` method.
+// Multiple `StreamingRecognizeRequest` messages are sent. The first message
+// must contain a `streaming_config` message and must not contain `audio` data.
+// All subsequent messages must contain `audio` data and must not contain a
+// `streaming_config` message.
+message StreamingRecognizeRequest {
+  // The streaming request, which is either a streaming config or audio content.
+  oneof streaming_request {
+    // Provides information to the recognizer that specifies how to process the
+    // request. The first `StreamingRecognizeRequest` message must contain a
+    // `streaming_config`  message.
+    StreamingRecognitionConfig streaming_config = 1;
+
+    // The audio data to be recognized. Sequential chunks of audio data are sent
+    // in sequential `StreamingRecognizeRequest` messages. The first
+    // `StreamingRecognizeRequest` message must not contain `audio_content` data
+    // and all subsequent `StreamingRecognizeRequest` messages must contain
+    // `audio_content` data. The audio bytes must be encoded as specified in
+    // `RecognitionConfig`. Note: as with all bytes fields, protobuffers use a
+    // pure binary representation (not base64). See
+    // [content limits](/speech-to-text/quotas#content).
+    bytes audio_content = 2;
+  }
+}
+
+// Provides information to the recognizer that specifies how to process the
+// request.
+message StreamingRecognitionConfig {
+  // *Required* Provides information to the recognizer that specifies how to
+  // process the request.
+  RecognitionConfig config = 1;
+
+  // *Optional* If `false` or omitted, the recognizer will perform continuous
+  // recognition (continuing to wait for and process audio even if the user
+  // pauses speaking) until the client closes the input stream (gRPC API) or
+  // until the maximum time limit has been reached. May return multiple
+  // `StreamingRecognitionResult`s with the `is_final` flag set to `true`.
+  //
+  // If `true`, the recognizer will detect a single spoken utterance. When it
+  // detects that the user has paused or stopped speaking, it will return an
+  // `END_OF_SINGLE_UTTERANCE` event and cease recognition. It will return no
+  // more than one `StreamingRecognitionResult` with the `is_final` flag set to
+  // `true`.
+  bool single_utterance = 2;
+
+  // *Optional* If `true`, interim results (tentative hypotheses) may be
+  // returned as they become available (these interim results are indicated with
+  // the `is_final=false` flag).
+  // If `false` or omitted, only `is_final=true` result(s) are returned.
+  bool interim_results = 3;
+}
+
+// Provides information to the recognizer that specifies how to process the
+// request.
+message RecognitionConfig {
+  // The encoding of the audio data sent in the request.
+  //
+  // All encodings support only 1 channel (mono) audio.
+  //
+  // For best results, the audio source should be captured and transmitted using
+  // a lossless encoding (`FLAC` or `LINEAR16`). The accuracy of the speech
+  // recognition can be reduced if lossy codecs are used to capture or transmit
+  // audio, particularly if background noise is present. Lossy codecs include
+  // `MULAW`, `AMR`, `AMR_WB`, `OGG_OPUS`, and `SPEEX_WITH_HEADER_BYTE`.
+  //
+  // The `FLAC` and `WAV` audio file formats include a header that describes the
+  // included audio content. You can request recognition for `WAV` files that
+  // contain either `LINEAR16` or `MULAW` encoded audio.
+  // If you send `FLAC` or `WAV` audio file format in
+  // your request, you do not need to specify an `AudioEncoding`; the audio
+  // encoding format is determined from the file header. If you specify
+  // an `AudioEncoding` when you send  send `FLAC` or `WAV` audio, the
+  // encoding configuration must match the encoding described in the audio
+  // header; otherwise the request returns an
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT] error code.
+  enum AudioEncoding {
+    // Not specified.
+    ENCODING_UNSPECIFIED = 0;
+
+    // Uncompressed 16-bit signed little-endian samples (Linear PCM).
+    LINEAR16 = 1;
+
+    // `FLAC` (Free Lossless Audio
+    // Codec) is the recommended encoding because it is
+    // lossless--therefore recognition is not compromised--and
+    // requires only about half the bandwidth of `LINEAR16`. `FLAC` stream
+    // encoding supports 16-bit and 24-bit samples, however, not all fields in
+    // `STREAMINFO` are supported.
+    FLAC = 2;
+
+    // 8-bit samples that compand 14-bit audio samples using G.711 PCMU/mu-law.
+    MULAW = 3;
+
+    // Adaptive Multi-Rate Narrowband codec. `sample_rate_hertz` must be 8000.
+    AMR = 4;
+
+    // Adaptive Multi-Rate Wideband codec. `sample_rate_hertz` must be 16000.
+    AMR_WB = 5;
+
+    // Opus encoded audio frames in Ogg container
+    // ([OggOpus](https://wiki.xiph.org/OggOpus)).
+    // `sample_rate_hertz` must be one of 8000, 12000, 16000, 24000, or 48000.
+    OGG_OPUS = 6;
+
+    // Although the use of lossy encodings is not recommended, if a very low
+    // bitrate encoding is required, `OGG_OPUS` is highly preferred over
+    // Speex encoding. The [Speex](https://speex.org/)  encoding supported by
+    // Cloud Speech API has a header byte in each block, as in MIME type
+    // `audio/x-speex-with-header-byte`.
+    // It is a variant of the RTP Speex encoding defined in
+    // [RFC 5574](https://tools.ietf.org/html/rfc5574).
+    // The stream is a sequence of blocks, one block per RTP packet. Each block
+    // starts with a byte containing the length of the block, in bytes, followed
+    // by one or more frames of Speex data, padded to an integral number of
+    // bytes (octets) as specified in RFC 5574. In other words, each RTP header
+    // is replaced with a single byte containing the block length. Only Speex
+    // wideband is supported. `sample_rate_hertz` must be 16000.
+    SPEEX_WITH_HEADER_BYTE = 7;
+  }
+
+  // Encoding of audio data sent in all `RecognitionAudio` messages.
+  // This field is optional for `FLAC` and `WAV` audio files and required
+  // for all other audio formats. For details, see [AudioEncoding][google.cloud.speech.v1p1beta1.RecognitionConfig.AudioEncoding].
+  AudioEncoding encoding = 1;
+
+  // Sample rate in Hertz of the audio data sent in all
+  // `RecognitionAudio` messages. Valid values are: 8000-48000.
+  // 16000 is optimal. For best results, set the sampling rate of the audio
+  // source to 16000 Hz. If that's not possible, use the native sample rate of
+  // the audio source (instead of re-sampling).
+  // This field is optional for `FLAC` and `WAV` audio files and required
+  // for all other audio formats. For details, see [AudioEncoding][google.cloud.speech.v1p1beta1.RecognitionConfig.AudioEncoding].
+  int32 sample_rate_hertz = 2;
+
+  // *Optional* The number of channels in the input audio data.
+  // ONLY set this for MULTI-CHANNEL recognition.
+  // Valid values for LINEAR16 and FLAC are `1`-`8`.
+  // Valid values for OGG_OPUS are '1'-'254'.
+  // Valid value for MULAW, AMR, AMR_WB and SPEEX_WITH_HEADER_BYTE is only `1`.
+  // If `0` or omitted, defaults to one channel (mono).
+  // Note: We only recognize the first channel by default.
+  // To perform independent recognition on each channel set
+  // `enable_separate_recognition_per_channel` to 'true'.
+  int32 audio_channel_count = 7;
+
+  // This needs to be set to ‘true’ explicitly and `audio_channel_count` > 1
+  // to get each channel recognized separately. The recognition result will
+  // contain a `channel_tag` field to state which channel that result belongs
+  // to. If this is not true, we will only recognize the first channel. The
+  // request is billed cumulatively for all channels recognized:
+  // `audio_channel_count` multiplied by the length of the audio.
+  bool enable_separate_recognition_per_channel = 12;
+
+  // *Required* The language of the supplied audio as a
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag.
+  // Example: "en-US".
+  // See [Language Support](/speech-to-text/docs/languages)
+  // for a list of the currently supported language codes.
+  string language_code = 3;
+
+  // *Optional* A list of up to 3 additional
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tags,
+  // listing possible alternative languages of the supplied audio.
+  // See [Language Support](/speech-to-text/docs/languages)
+  // for a list of the currently supported language codes.
+  // If alternative languages are listed, recognition result will contain
+  // recognition in the most likely language detected including the main
+  // language_code. The recognition result will include the language tag
+  // of the language detected in the audio.
+  // Note: This feature is only supported for Voice Command and Voice Search
+  // use cases and performance may vary for other use cases (e.g., phone call
+  // transcription).
+  repeated string alternative_language_codes = 18;
+
+  // *Optional* Maximum number of recognition hypotheses to be returned.
+  // Specifically, the maximum number of `SpeechRecognitionAlternative` messages
+  // within each `SpeechRecognitionResult`.
+  // The server may return fewer than `max_alternatives`.
+  // Valid values are `0`-`30`. A value of `0` or `1` will return a maximum of
+  // one. If omitted, will return a maximum of one.
+  int32 max_alternatives = 4;
+
+  // *Optional* If set to `true`, the server will attempt to filter out
+  // profanities, replacing all but the initial character in each filtered word
+  // with asterisks, e.g. "f***". If set to `false` or omitted, profanities
+  // won't be filtered out.
+  bool profanity_filter = 5;
+
+  // *Optional* array of [SpeechContext][google.cloud.speech.v1p1beta1.SpeechContext].
+  // A means to provide context to assist the speech recognition. For more
+  // information, see [Phrase Hints](/speech-to-text/docs/basics#phrase-hints).
+  repeated SpeechContext speech_contexts = 6;
+
+  // *Optional* If `true`, the top result includes a list of words and
+  // the start and end time offsets (timestamps) for those words. If
+  // `false`, no word-level time offset information is returned. The default is
+  // `false`.
+  bool enable_word_time_offsets = 8;
+
+  // *Optional* If `true`, the top result includes a list of words and the
+  // confidence for those words. If `false`, no word-level confidence
+  // information is returned. The default is `false`.
+  bool enable_word_confidence = 15;
+
+  // *Optional* If 'true', adds punctuation to recognition result hypotheses.
+  // This feature is only available in select languages. Setting this for
+  // requests in other languages has no effect at all.
+  // The default 'false' value does not add punctuation to result hypotheses.
+  // Note: This is currently offered as an experimental service, complimentary
+  // to all users. In the future this may be exclusively available as a
+  // premium feature.
+  bool enable_automatic_punctuation = 11;
+
+  // *Optional* If 'true', enables speaker detection for each recognized word in
+  // the top alternative of the recognition result using a speaker_tag provided
+  // in the WordInfo.
+  // Note: When this is true, we send all the words from the beginning of the
+  // audio for the top alternative in every consecutive STREAMING responses.
+  // This is done in order to improve our speaker tags as our models learn to
+  // identify the speakers in the conversation over time.
+  // For non-streaming requests, the diarization results will be provided only
+  // in the top alternative of the FINAL SpeechRecognitionResult.
+  bool enable_speaker_diarization = 16;
+
+  // *Optional*
+  // If set, specifies the estimated number of speakers in the conversation.
+  // If not set, defaults to '2'.
+  // Ignored unless enable_speaker_diarization is set to true."
+  int32 diarization_speaker_count = 17;
+
+  // *Optional* Metadata regarding this request.
+  RecognitionMetadata metadata = 9;
+
+  // *Optional* Which model to select for the given request. Select the model
+  // best suited to your domain to get best results. If a model is not
+  // explicitly specified, then we auto-select a model based on the parameters
+  // in the RecognitionConfig.
+  // <table>
+  //   <tr>
+  //     <td><b>Model</b></td>
+  //     <td><b>Description</b></td>
+  //   </tr>
+  //   <tr>
+  //     <td><code>command_and_search</code></td>
+  //     <td>Best for short queries such as voice commands or voice search.</td>
+  //   </tr>
+  //   <tr>
+  //     <td><code>phone_call</code></td>
+  //     <td>Best for audio that originated from a phone call (typically
+  //     recorded at an 8khz sampling rate).</td>
+  //   </tr>
+  //   <tr>
+  //     <td><code>video</code></td>
+  //     <td>Best for audio that originated from from video or includes multiple
+  //         speakers. Ideally the audio is recorded at a 16khz or greater
+  //         sampling rate. This is a premium model that costs more than the
+  //         standard rate.</td>
+  //   </tr>
+  //   <tr>
+  //     <td><code>default</code></td>
+  //     <td>Best for audio that is not one of the specific audio models.
+  //         For example, long-form audio. Ideally the audio is high-fidelity,
+  //         recorded at a 16khz or greater sampling rate.</td>
+  //   </tr>
+  // </table>
+  string model = 13;
+
+  // *Optional* Set to true to use an enhanced model for speech recognition.
+  // If `use_enhanced` is set to true and the `model` field is not set, then
+  // an appropriate enhanced model is chosen if:
+  // 1. project is eligible for requesting enhanced models
+  // 2. an enhanced model exists for the audio
+  //
+  // If `use_enhanced` is true and an enhanced version of the specified model
+  // does not exist, then the speech is recognized using the standard version
+  // of the specified model.
+  //
+  // Enhanced speech models require that you opt-in to data logging using
+  // instructions in the
+  // [documentation](/speech-to-text/docs/enable-data-logging). If you set
+  // `use_enhanced` to true and you have not enabled audio logging, then you
+  // will receive an error.
+  bool use_enhanced = 14;
+}
+
+// Description of audio data to be recognized.
+message RecognitionMetadata {
+  // Use case categories that the audio recognition request can be described
+  // by.
+  enum InteractionType {
+    // Use case is either unknown or is something other than one of the other
+    // values below.
+    INTERACTION_TYPE_UNSPECIFIED = 0;
+
+    // Multiple people in a conversation or discussion. For example in a
+    // meeting with two or more people actively participating. Typically
+    // all the primary people speaking would be in the same room (if not,
+    // see PHONE_CALL)
+    DISCUSSION = 1;
+
+    // One or more persons lecturing or presenting to others, mostly
+    // uninterrupted.
+    PRESENTATION = 2;
+
+    // A phone-call or video-conference in which two or more people, who are
+    // not in the same room, are actively participating.
+    PHONE_CALL = 3;
+
+    // A recorded message intended for another person to listen to.
+    VOICEMAIL = 4;
+
+    // Professionally produced audio (eg. TV Show, Podcast).
+    PROFESSIONALLY_PRODUCED = 5;
+
+    // Transcribe spoken questions and queries into text.
+    VOICE_SEARCH = 6;
+
+    // Transcribe voice commands, such as for controlling a device.
+    VOICE_COMMAND = 7;
+
+    // Transcribe speech to text to create a written document, such as a
+    // text-message, email or report.
+    DICTATION = 8;
+  }
+
+  // Enumerates the types of capture settings describing an audio file.
+  enum MicrophoneDistance {
+    // Audio type is not known.
+    MICROPHONE_DISTANCE_UNSPECIFIED = 0;
+
+    // The audio was captured from a closely placed microphone. Eg. phone,
+    // dictaphone, or handheld microphone. Generally if there speaker is within
+    // 1 meter of the microphone.
+    NEARFIELD = 1;
+
+    // The speaker if within 3 meters of the microphone.
+    MIDFIELD = 2;
+
+    // The speaker is more than 3 meters away from the microphone.
+    FARFIELD = 3;
+  }
+
+  // The original media the speech was recorded on.
+  enum OriginalMediaType {
+    // Unknown original media type.
+    ORIGINAL_MEDIA_TYPE_UNSPECIFIED = 0;
+
+    // The speech data is an audio recording.
+    AUDIO = 1;
+
+    // The speech data originally recorded on a video.
+    VIDEO = 2;
+  }
+
+  // The type of device the speech was recorded with.
+  enum RecordingDeviceType {
+    // The recording device is unknown.
+    RECORDING_DEVICE_TYPE_UNSPECIFIED = 0;
+
+    // Speech was recorded on a smartphone.
+    SMARTPHONE = 1;
+
+    // Speech was recorded using a personal computer or tablet.
+    PC = 2;
+
+    // Speech was recorded over a phone line.
+    PHONE_LINE = 3;
+
+    // Speech was recorded in a vehicle.
+    VEHICLE = 4;
+
+    // Speech was recorded outdoors.
+    OTHER_OUTDOOR_DEVICE = 5;
+
+    // Speech was recorded indoors.
+    OTHER_INDOOR_DEVICE = 6;
+  }
+
+  // The use case most closely describing the audio content to be recognized.
+  InteractionType interaction_type = 1;
+
+  // The industry vertical to which this speech recognition request most
+  // closely applies. This is most indicative of the topics contained
+  // in the audio.  Use the 6-digit NAICS code to identify the industry
+  // vertical - see https://www.naics.com/search/.
+  uint32 industry_naics_code_of_audio = 3;
+
+  // The audio type that most closely describes the audio being recognized.
+  MicrophoneDistance microphone_distance = 4;
+
+  // The original media the speech was recorded on.
+  OriginalMediaType original_media_type = 5;
+
+  // The type of device the speech was recorded with.
+  RecordingDeviceType recording_device_type = 6;
+
+  // The device used to make the recording.  Examples 'Nexus 5X' or
+  // 'Polycom SoundStation IP 6000' or 'POTS' or 'VoIP' or
+  // 'Cardioid Microphone'.
+  string recording_device_name = 7;
+
+  // Mime type of the original audio file.  For example `audio/m4a`,
+  // `audio/x-alaw-basic`, `audio/mp3`, `audio/3gpp`.
+  // A list of possible audio mime types is maintained at
+  // http://www.iana.org/assignments/media-types/media-types.xhtml#audio
+  string original_mime_type = 8;
+
+  // Obfuscated (privacy-protected) ID of the user, to identify number of
+  // unique users using the service.
+  int64 obfuscated_id = 9;
+
+  // Description of the content. Eg. "Recordings of federal supreme court
+  // hearings from 2012".
+  string audio_topic = 10;
+}
+
+// Provides "hints" to the speech recognizer to favor specific words and phrases
+// in the results.
+message SpeechContext {
+  // *Optional* A list of strings containing words and phrases "hints" so that
+  // the speech recognition is more likely to recognize them. This can be used
+  // to improve the accuracy for specific words and phrases, for example, if
+  // specific commands are typically spoken by the user. This can also be used
+  // to add additional words to the vocabulary of the recognizer. See
+  // [usage limits](/speech-to-text/quotas#content).
+  repeated string phrases = 1;
+}
+
+// Contains audio data in the encoding specified in the `RecognitionConfig`.
+// Either `content` or `uri` must be supplied. Supplying both or neither
+// returns [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]. See
+// [content limits](/speech-to-text/quotas#content).
+message RecognitionAudio {
+  // The audio source, which is either inline content or a Google Cloud
+  // Storage uri.
+  oneof audio_source {
+    // The audio data bytes encoded as specified in
+    // `RecognitionConfig`. Note: as with all bytes fields, protobuffers use a
+    // pure binary representation, whereas JSON representations use base64.
+    bytes content = 1;
+
+    // URI that points to a file that contains audio data bytes as specified in
+    // `RecognitionConfig`. The file must not be compressed (for example, gzip).
+    // Currently, only Google Cloud Storage URIs are
+    // supported, which must be specified in the following format:
+    // `gs://bucket_name/object_name` (other URI formats return
+    // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+    // [Request URIs](https://cloud.google.com/storage/docs/reference-uris).
+    string uri = 2;
+  }
+}
+
+// The only message returned to the client by the `Recognize` method. It
+// contains the result as zero or more sequential `SpeechRecognitionResult`
+// messages.
+message RecognizeResponse {
+  // Output only. Sequential list of transcription results corresponding to
+  // sequential portions of audio.
+  repeated SpeechRecognitionResult results = 2;
+}
+
+// The only message returned to the client by the `LongRunningRecognize` method.
+// It contains the result as zero or more sequential `SpeechRecognitionResult`
+// messages. It is included in the `result.response` field of the `Operation`
+// returned by the `GetOperation` call of the `google::longrunning::Operations`
+// service.
+message LongRunningRecognizeResponse {
+  // Output only. Sequential list of transcription results corresponding to
+  // sequential portions of audio.
+  repeated SpeechRecognitionResult results = 2;
+}
+
+// Describes the progress of a long-running `LongRunningRecognize` call. It is
+// included in the `metadata` field of the `Operation` returned by the
+// `GetOperation` call of the `google::longrunning::Operations` service.
+message LongRunningRecognizeMetadata {
+  // Approximate percentage of audio processed thus far. Guaranteed to be 100
+  // when the audio is fully processed and the results are available.
+  int32 progress_percent = 1;
+
+  // Time when the request was received.
+  google.protobuf.Timestamp start_time = 2;
+
+  // Time of the most recent processing update.
+  google.protobuf.Timestamp last_update_time = 3;
+}
+
+// `StreamingRecognizeResponse` is the only message returned to the client by
+// `StreamingRecognize`. A series of zero or more `StreamingRecognizeResponse`
+// messages are streamed back to the client. If there is no recognizable
+// audio, and `single_utterance` is set to false, then no messages are streamed
+// back to the client.
+//
+// Here's an example of a series of ten `StreamingRecognizeResponse`s that might
+// be returned while processing audio:
+//
+// 1. results { alternatives { transcript: "tube" } stability: 0.01 }
+//
+// 2. results { alternatives { transcript: "to be a" } stability: 0.01 }
+//
+// 3. results { alternatives { transcript: "to be" } stability: 0.9 }
+//    results { alternatives { transcript: " or not to be" } stability: 0.01 }
+//
+// 4. results { alternatives { transcript: "to be or not to be"
+//                             confidence: 0.92 }
+//              alternatives { transcript: "to bee or not to bee" }
+//              is_final: true }
+//
+// 5. results { alternatives { transcript: " that's" } stability: 0.01 }
+//
+// 6. results { alternatives { transcript: " that is" } stability: 0.9 }
+//    results { alternatives { transcript: " the question" } stability: 0.01 }
+//
+// 7. results { alternatives { transcript: " that is the question"
+//                             confidence: 0.98 }
+//              alternatives { transcript: " that was the question" }
+//              is_final: true }
+//
+// Notes:
+//
+// - Only two of the above responses #4 and #7 contain final results; they are
+//   indicated by `is_final: true`. Concatenating these together generates the
+//   full transcript: "to be or not to be that is the question".
+//
+// - The others contain interim `results`. #3 and #6 contain two interim
+//   `results`: the first portion has a high stability and is less likely to
+//   change; the second portion has a low stability and is very likely to
+//   change. A UI designer might choose to show only high stability `results`.
+//
+// - The specific `stability` and `confidence` values shown above are only for
+//   illustrative purposes. Actual values may vary.
+//
+// - In each response, only one of these fields will be set:
+//     `error`,
+//     `speech_event_type`, or
+//     one or more (repeated) `results`.
+message StreamingRecognizeResponse {
+  // Indicates the type of speech event.
+  enum SpeechEventType {
+    // No speech event specified.
+    SPEECH_EVENT_UNSPECIFIED = 0;
+
+    // This event indicates that the server has detected the end of the user's
+    // speech utterance and expects no additional speech. Therefore, the server
+    // will not process additional audio (although it may subsequently return
+    // additional results). The client should stop sending additional audio
+    // data, half-close the gRPC connection, and wait for any additional results
+    // until the server closes the gRPC connection. This event is only sent if
+    // `single_utterance` was set to `true`, and is not used otherwise.
+    END_OF_SINGLE_UTTERANCE = 1;
+  }
+
+  // Output only. If set, returns a [google.rpc.Status][google.rpc.Status] message that
+  // specifies the error for the operation.
+  google.rpc.Status error = 1;
+
+  // Output only. This repeated list contains zero or more results that
+  // correspond to consecutive portions of the audio currently being processed.
+  // It contains zero or one `is_final=true` result (the newly settled portion),
+  // followed by zero or more `is_final=false` results (the interim results).
+  repeated StreamingRecognitionResult results = 2;
+
+  // Output only. Indicates the type of speech event.
+  SpeechEventType speech_event_type = 4;
+}
+
+// A streaming speech recognition result corresponding to a portion of the audio
+// that is currently being processed.
+message StreamingRecognitionResult {
+  // Output only. May contain one or more recognition hypotheses (up to the
+  // maximum specified in `max_alternatives`).
+  // These alternatives are ordered in terms of accuracy, with the top (first)
+  // alternative being the most probable, as ranked by the recognizer.
+  repeated SpeechRecognitionAlternative alternatives = 1;
+
+  // Output only. If `false`, this `StreamingRecognitionResult` represents an
+  // interim result that may change. If `true`, this is the final time the
+  // speech service will return this particular `StreamingRecognitionResult`,
+  // the recognizer will not return any further hypotheses for this portion of
+  // the transcript and corresponding audio.
+  bool is_final = 2;
+
+  // Output only. An estimate of the likelihood that the recognizer will not
+  // change its guess about this interim result. Values range from 0.0
+  // (completely unstable) to 1.0 (completely stable).
+  // This field is only provided for interim results (`is_final=false`).
+  // The default of 0.0 is a sentinel value indicating `stability` was not set.
+  float stability = 3;
+
+  // Output only. Time offset of the end of this result relative to the
+  // beginning of the audio.
+  google.protobuf.Duration result_end_time = 4;
+
+  // For multi-channel audio, this is the channel number corresponding to the
+  // recognized result for the audio from that channel.
+  // For audio_channel_count = N, its output values can range from '1' to 'N'.
+  int32 channel_tag = 5;
+
+  // Output only. The
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag of the
+  // language in this result. This language code was detected to have the most
+  // likelihood of being spoken in the audio.
+  string language_code = 6;
+}
+
+// A speech recognition result corresponding to a portion of the audio.
+message SpeechRecognitionResult {
+  // Output only. May contain one or more recognition hypotheses (up to the
+  // maximum specified in `max_alternatives`).
+  // These alternatives are ordered in terms of accuracy, with the top (first)
+  // alternative being the most probable, as ranked by the recognizer.
+  repeated SpeechRecognitionAlternative alternatives = 1;
+
+  // For multi-channel audio, this is the channel number corresponding to the
+  // recognized result for the audio from that channel.
+  // For audio_channel_count = N, its output values can range from '1' to 'N'.
+  int32 channel_tag = 2;
+
+  // Output only. The
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag of the
+  // language in this result. This language code was detected to have the most
+  // likelihood of being spoken in the audio.
+  string language_code = 5;
+}
+
+// Alternative hypotheses (a.k.a. n-best list).
+message SpeechRecognitionAlternative {
+  // Output only. Transcript text representing the words that the user spoke.
+  string transcript = 1;
+
+  // Output only. The confidence estimate between 0.0 and 1.0. A higher number
+  // indicates an estimated greater likelihood that the recognized words are
+  // correct. This field is set only for the top alternative of a non-streaming
+  // result or, of a streaming result where `is_final=true`.
+  // This field is not guaranteed to be accurate and users should not rely on it
+  // to be always provided.
+  // The default of 0.0 is a sentinel value indicating `confidence` was not set.
+  float confidence = 2;
+
+  // Output only. A list of word-specific information for each recognized word.
+  // Note: When `enable_speaker_diarization` is true, you will see all the words
+  // from the beginning of the audio.
+  repeated WordInfo words = 3;
+}
+
+// Word-specific information for recognized words.
+message WordInfo {
+  // Output only. Time offset relative to the beginning of the audio,
+  // and corresponding to the start of the spoken word.
+  // This field is only set if `enable_word_time_offsets=true` and only
+  // in the top hypothesis.
+  // This is an experimental feature and the accuracy of the time offset can
+  // vary.
+  google.protobuf.Duration start_time = 1;
+
+  // Output only. Time offset relative to the beginning of the audio,
+  // and corresponding to the end of the spoken word.
+  // This field is only set if `enable_word_time_offsets=true` and only
+  // in the top hypothesis.
+  // This is an experimental feature and the accuracy of the time offset can
+  // vary.
+  google.protobuf.Duration end_time = 2;
+
+  // Output only. The word corresponding to this set of information.
+  string word = 3;
+
+  // Output only. The confidence estimate between 0.0 and 1.0. A higher number
+  // indicates an estimated greater likelihood that the recognized words are
+  // correct. This field is set only for the top alternative of a non-streaming
+  // result or, of a streaming result where `is_final=true`.
+  // This field is not guaranteed to be accurate and users should not rely on it
+  // to be always provided.
+  // The default of 0.0 is a sentinel value indicating `confidence` was not set.
+  float confidence = 4;
+
+  // Output only. A distinct integer value is assigned for every speaker within
+  // the audio. This field specifies which one of those speakers was detected to
+  // have spoken this word. Value ranges from '1' to diarization_speaker_count.
+  // speaker_tag is set if enable_speaker_diarization = 'true' and only in the
+  // top alternative.
+  int32 speaker_tag = 5;
+}
diff --git a/speech/google/cloud/speech_v1/proto/cloud_speech_pb2.py b/speech/google/cloud/speech_v1/proto/cloud_speech_pb2.py
index fa7a52a62d8f..18ad3cf53e2d 100644
--- a/speech/google/cloud/speech_v1/proto/cloud_speech_pb2.py
+++ b/speech/google/cloud/speech_v1/proto/cloud_speech_pb2.py
@@ -1967,3 +1967,4 @@
 DESCRIPTOR.services_by_name["Speech"] = _SPEECH
 
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/speech/google/cloud/speech_v1p1beta1/proto/cloud_speech.proto b/speech/google/cloud/speech_v1p1beta1/proto/cloud_speech.proto
new file mode 100644
index 000000000000..53283d3b7d33
--- /dev/null
+++ b/speech/google/cloud/speech_v1p1beta1/proto/cloud_speech.proto
@@ -0,0 +1,765 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.speech.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1;speech";
+option java_multiple_files = true;
+option java_outer_classname = "SpeechProto";
+option java_package = "com.google.cloud.speech.v1p1beta1";
+
+
+// Service that implements Google Cloud Speech API.
+service Speech {
+  // Performs synchronous speech recognition: receive results after all audio
+  // has been sent and processed.
+  rpc Recognize(RecognizeRequest) returns (RecognizeResponse) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/speech:recognize"
+      body: "*"
+    };
+  }
+
+  // Performs asynchronous speech recognition: receive results via the
+  // google.longrunning.Operations interface. Returns either an
+  // `Operation.error` or an `Operation.response` which contains
+  // a `LongRunningRecognizeResponse` message.
+  rpc LongRunningRecognize(LongRunningRecognizeRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/speech:longrunningrecognize"
+      body: "*"
+    };
+  }
+
+  // Performs bidirectional streaming speech recognition: receive results while
+  // sending audio. This method is only available via the gRPC API (not REST).
+  rpc StreamingRecognize(stream StreamingRecognizeRequest) returns (stream StreamingRecognizeResponse) {
+  }
+}
+
+// The top-level message sent by the client for the `Recognize` method.
+message RecognizeRequest {
+  // *Required* Provides information to the recognizer that specifies how to
+  // process the request.
+  RecognitionConfig config = 1;
+
+  // *Required* The audio data to be recognized.
+  RecognitionAudio audio = 2;
+}
+
+// The top-level message sent by the client for the `LongRunningRecognize`
+// method.
+message LongRunningRecognizeRequest {
+  // *Required* Provides information to the recognizer that specifies how to
+  // process the request.
+  RecognitionConfig config = 1;
+
+  // *Required* The audio data to be recognized.
+  RecognitionAudio audio = 2;
+}
+
+// The top-level message sent by the client for the `StreamingRecognize` method.
+// Multiple `StreamingRecognizeRequest` messages are sent. The first message
+// must contain a `streaming_config` message and must not contain `audio` data.
+// All subsequent messages must contain `audio` data and must not contain a
+// `streaming_config` message.
+message StreamingRecognizeRequest {
+  // The streaming request, which is either a streaming config or audio content.
+  oneof streaming_request {
+    // Provides information to the recognizer that specifies how to process the
+    // request. The first `StreamingRecognizeRequest` message must contain a
+    // `streaming_config`  message.
+    StreamingRecognitionConfig streaming_config = 1;
+
+    // The audio data to be recognized. Sequential chunks of audio data are sent
+    // in sequential `StreamingRecognizeRequest` messages. The first
+    // `StreamingRecognizeRequest` message must not contain `audio_content` data
+    // and all subsequent `StreamingRecognizeRequest` messages must contain
+    // `audio_content` data. The audio bytes must be encoded as specified in
+    // `RecognitionConfig`. Note: as with all bytes fields, protobuffers use a
+    // pure binary representation (not base64). See
+    // [content limits](/speech-to-text/quotas#content).
+    bytes audio_content = 2;
+  }
+}
+
+// Provides information to the recognizer that specifies how to process the
+// request.
+message StreamingRecognitionConfig {
+  // *Required* Provides information to the recognizer that specifies how to
+  // process the request.
+  RecognitionConfig config = 1;
+
+  // *Optional* If `false` or omitted, the recognizer will perform continuous
+  // recognition (continuing to wait for and process audio even if the user
+  // pauses speaking) until the client closes the input stream (gRPC API) or
+  // until the maximum time limit has been reached. May return multiple
+  // `StreamingRecognitionResult`s with the `is_final` flag set to `true`.
+  //
+  // If `true`, the recognizer will detect a single spoken utterance. When it
+  // detects that the user has paused or stopped speaking, it will return an
+  // `END_OF_SINGLE_UTTERANCE` event and cease recognition. It will return no
+  // more than one `StreamingRecognitionResult` with the `is_final` flag set to
+  // `true`.
+  bool single_utterance = 2;
+
+  // *Optional* If `true`, interim results (tentative hypotheses) may be
+  // returned as they become available (these interim results are indicated with
+  // the `is_final=false` flag).
+  // If `false` or omitted, only `is_final=true` result(s) are returned.
+  bool interim_results = 3;
+}
+
+// Provides information to the recognizer that specifies how to process the
+// request.
+message RecognitionConfig {
+  // The encoding of the audio data sent in the request.
+  //
+  // All encodings support only 1 channel (mono) audio.
+  //
+  // For best results, the audio source should be captured and transmitted using
+  // a lossless encoding (`FLAC` or `LINEAR16`). The accuracy of the speech
+  // recognition can be reduced if lossy codecs are used to capture or transmit
+  // audio, particularly if background noise is present. Lossy codecs include
+  // `MULAW`, `AMR`, `AMR_WB`, `OGG_OPUS`, and `SPEEX_WITH_HEADER_BYTE`.
+  //
+  // The `FLAC` and `WAV` audio file formats include a header that describes the
+  // included audio content. You can request recognition for `WAV` files that
+  // contain either `LINEAR16` or `MULAW` encoded audio.
+  // If you send `FLAC` or `WAV` audio file format in
+  // your request, you do not need to specify an `AudioEncoding`; the audio
+  // encoding format is determined from the file header. If you specify
+  // an `AudioEncoding` when you send  send `FLAC` or `WAV` audio, the
+  // encoding configuration must match the encoding described in the audio
+  // header; otherwise the request returns an
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT] error code.
+  enum AudioEncoding {
+    // Not specified.
+    ENCODING_UNSPECIFIED = 0;
+
+    // Uncompressed 16-bit signed little-endian samples (Linear PCM).
+    LINEAR16 = 1;
+
+    // `FLAC` (Free Lossless Audio
+    // Codec) is the recommended encoding because it is
+    // lossless--therefore recognition is not compromised--and
+    // requires only about half the bandwidth of `LINEAR16`. `FLAC` stream
+    // encoding supports 16-bit and 24-bit samples, however, not all fields in
+    // `STREAMINFO` are supported.
+    FLAC = 2;
+
+    // 8-bit samples that compand 14-bit audio samples using G.711 PCMU/mu-law.
+    MULAW = 3;
+
+    // Adaptive Multi-Rate Narrowband codec. `sample_rate_hertz` must be 8000.
+    AMR = 4;
+
+    // Adaptive Multi-Rate Wideband codec. `sample_rate_hertz` must be 16000.
+    AMR_WB = 5;
+
+    // Opus encoded audio frames in Ogg container
+    // ([OggOpus](https://wiki.xiph.org/OggOpus)).
+    // `sample_rate_hertz` must be one of 8000, 12000, 16000, 24000, or 48000.
+    OGG_OPUS = 6;
+
+    // Although the use of lossy encodings is not recommended, if a very low
+    // bitrate encoding is required, `OGG_OPUS` is highly preferred over
+    // Speex encoding. The [Speex](https://speex.org/)  encoding supported by
+    // Cloud Speech API has a header byte in each block, as in MIME type
+    // `audio/x-speex-with-header-byte`.
+    // It is a variant of the RTP Speex encoding defined in
+    // [RFC 5574](https://tools.ietf.org/html/rfc5574).
+    // The stream is a sequence of blocks, one block per RTP packet. Each block
+    // starts with a byte containing the length of the block, in bytes, followed
+    // by one or more frames of Speex data, padded to an integral number of
+    // bytes (octets) as specified in RFC 5574. In other words, each RTP header
+    // is replaced with a single byte containing the block length. Only Speex
+    // wideband is supported. `sample_rate_hertz` must be 16000.
+    SPEEX_WITH_HEADER_BYTE = 7;
+  }
+
+  // Encoding of audio data sent in all `RecognitionAudio` messages.
+  // This field is optional for `FLAC` and `WAV` audio files and required
+  // for all other audio formats. For details, see [AudioEncoding][google.cloud.speech.v1p1beta1.RecognitionConfig.AudioEncoding].
+  AudioEncoding encoding = 1;
+
+  // Sample rate in Hertz of the audio data sent in all
+  // `RecognitionAudio` messages. Valid values are: 8000-48000.
+  // 16000 is optimal. For best results, set the sampling rate of the audio
+  // source to 16000 Hz. If that's not possible, use the native sample rate of
+  // the audio source (instead of re-sampling).
+  // This field is optional for `FLAC` and `WAV` audio files and required
+  // for all other audio formats. For details, see [AudioEncoding][google.cloud.speech.v1p1beta1.RecognitionConfig.AudioEncoding].
+  int32 sample_rate_hertz = 2;
+
+  // *Optional* The number of channels in the input audio data.
+  // ONLY set this for MULTI-CHANNEL recognition.
+  // Valid values for LINEAR16 and FLAC are `1`-`8`.
+  // Valid values for OGG_OPUS are '1'-'254'.
+  // Valid value for MULAW, AMR, AMR_WB and SPEEX_WITH_HEADER_BYTE is only `1`.
+  // If `0` or omitted, defaults to one channel (mono).
+  // Note: We only recognize the first channel by default.
+  // To perform independent recognition on each channel set
+  // `enable_separate_recognition_per_channel` to 'true'.
+  int32 audio_channel_count = 7;
+
+  // This needs to be set to ‘true’ explicitly and `audio_channel_count` > 1
+  // to get each channel recognized separately. The recognition result will
+  // contain a `channel_tag` field to state which channel that result belongs
+  // to. If this is not true, we will only recognize the first channel. The
+  // request is billed cumulatively for all channels recognized:
+  // `audio_channel_count` multiplied by the length of the audio.
+  bool enable_separate_recognition_per_channel = 12;
+
+  // *Required* The language of the supplied audio as a
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag.
+  // Example: "en-US".
+  // See [Language Support](/speech-to-text/docs/languages)
+  // for a list of the currently supported language codes.
+  string language_code = 3;
+
+  // *Optional* A list of up to 3 additional
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tags,
+  // listing possible alternative languages of the supplied audio.
+  // See [Language Support](/speech-to-text/docs/languages)
+  // for a list of the currently supported language codes.
+  // If alternative languages are listed, recognition result will contain
+  // recognition in the most likely language detected including the main
+  // language_code. The recognition result will include the language tag
+  // of the language detected in the audio.
+  // Note: This feature is only supported for Voice Command and Voice Search
+  // use cases and performance may vary for other use cases (e.g., phone call
+  // transcription).
+  repeated string alternative_language_codes = 18;
+
+  // *Optional* Maximum number of recognition hypotheses to be returned.
+  // Specifically, the maximum number of `SpeechRecognitionAlternative` messages
+  // within each `SpeechRecognitionResult`.
+  // The server may return fewer than `max_alternatives`.
+  // Valid values are `0`-`30`. A value of `0` or `1` will return a maximum of
+  // one. If omitted, will return a maximum of one.
+  int32 max_alternatives = 4;
+
+  // *Optional* If set to `true`, the server will attempt to filter out
+  // profanities, replacing all but the initial character in each filtered word
+  // with asterisks, e.g. "f***". If set to `false` or omitted, profanities
+  // won't be filtered out.
+  bool profanity_filter = 5;
+
+  // *Optional* array of [SpeechContext][google.cloud.speech.v1p1beta1.SpeechContext].
+  // A means to provide context to assist the speech recognition. For more
+  // information, see [Phrase Hints](/speech-to-text/docs/basics#phrase-hints).
+  repeated SpeechContext speech_contexts = 6;
+
+  // *Optional* If `true`, the top result includes a list of words and
+  // the start and end time offsets (timestamps) for those words. If
+  // `false`, no word-level time offset information is returned. The default is
+  // `false`.
+  bool enable_word_time_offsets = 8;
+
+  // *Optional* If `true`, the top result includes a list of words and the
+  // confidence for those words. If `false`, no word-level confidence
+  // information is returned. The default is `false`.
+  bool enable_word_confidence = 15;
+
+  // *Optional* If 'true', adds punctuation to recognition result hypotheses.
+  // This feature is only available in select languages. Setting this for
+  // requests in other languages has no effect at all.
+  // The default 'false' value does not add punctuation to result hypotheses.
+  // Note: This is currently offered as an experimental service, complimentary
+  // to all users. In the future this may be exclusively available as a
+  // premium feature.
+  bool enable_automatic_punctuation = 11;
+
+  // *Optional* If 'true', enables speaker detection for each recognized word in
+  // the top alternative of the recognition result using a speaker_tag provided
+  // in the WordInfo.
+  // Note: When this is true, we send all the words from the beginning of the
+  // audio for the top alternative in every consecutive STREAMING responses.
+  // This is done in order to improve our speaker tags as our models learn to
+  // identify the speakers in the conversation over time.
+  // For non-streaming requests, the diarization results will be provided only
+  // in the top alternative of the FINAL SpeechRecognitionResult.
+  bool enable_speaker_diarization = 16;
+
+  // *Optional*
+  // If set, specifies the estimated number of speakers in the conversation.
+  // If not set, defaults to '2'.
+  // Ignored unless enable_speaker_diarization is set to true."
+  int32 diarization_speaker_count = 17;
+
+  // *Optional* Metadata regarding this request.
+  RecognitionMetadata metadata = 9;
+
+  // *Optional* Which model to select for the given request. Select the model
+  // best suited to your domain to get best results. If a model is not
+  // explicitly specified, then we auto-select a model based on the parameters
+  // in the RecognitionConfig.
+  // <table>
+  //   <tr>
+  //     <td><b>Model</b></td>
+  //     <td><b>Description</b></td>
+  //   </tr>
+  //   <tr>
+  //     <td><code>command_and_search</code></td>
+  //     <td>Best for short queries such as voice commands or voice search.</td>
+  //   </tr>
+  //   <tr>
+  //     <td><code>phone_call</code></td>
+  //     <td>Best for audio that originated from a phone call (typically
+  //     recorded at an 8khz sampling rate).</td>
+  //   </tr>
+  //   <tr>
+  //     <td><code>video</code></td>
+  //     <td>Best for audio that originated from from video or includes multiple
+  //         speakers. Ideally the audio is recorded at a 16khz or greater
+  //         sampling rate. This is a premium model that costs more than the
+  //         standard rate.</td>
+  //   </tr>
+  //   <tr>
+  //     <td><code>default</code></td>
+  //     <td>Best for audio that is not one of the specific audio models.
+  //         For example, long-form audio. Ideally the audio is high-fidelity,
+  //         recorded at a 16khz or greater sampling rate.</td>
+  //   </tr>
+  // </table>
+  string model = 13;
+
+  // *Optional* Set to true to use an enhanced model for speech recognition.
+  // If `use_enhanced` is set to true and the `model` field is not set, then
+  // an appropriate enhanced model is chosen if:
+  // 1. project is eligible for requesting enhanced models
+  // 2. an enhanced model exists for the audio
+  //
+  // If `use_enhanced` is true and an enhanced version of the specified model
+  // does not exist, then the speech is recognized using the standard version
+  // of the specified model.
+  //
+  // Enhanced speech models require that you opt-in to data logging using
+  // instructions in the
+  // [documentation](/speech-to-text/docs/enable-data-logging). If you set
+  // `use_enhanced` to true and you have not enabled audio logging, then you
+  // will receive an error.
+  bool use_enhanced = 14;
+}
+
+// Description of audio data to be recognized.
+message RecognitionMetadata {
+  // Use case categories that the audio recognition request can be described
+  // by.
+  enum InteractionType {
+    // Use case is either unknown or is something other than one of the other
+    // values below.
+    INTERACTION_TYPE_UNSPECIFIED = 0;
+
+    // Multiple people in a conversation or discussion. For example in a
+    // meeting with two or more people actively participating. Typically
+    // all the primary people speaking would be in the same room (if not,
+    // see PHONE_CALL)
+    DISCUSSION = 1;
+
+    // One or more persons lecturing or presenting to others, mostly
+    // uninterrupted.
+    PRESENTATION = 2;
+
+    // A phone-call or video-conference in which two or more people, who are
+    // not in the same room, are actively participating.
+    PHONE_CALL = 3;
+
+    // A recorded message intended for another person to listen to.
+    VOICEMAIL = 4;
+
+    // Professionally produced audio (eg. TV Show, Podcast).
+    PROFESSIONALLY_PRODUCED = 5;
+
+    // Transcribe spoken questions and queries into text.
+    VOICE_SEARCH = 6;
+
+    // Transcribe voice commands, such as for controlling a device.
+    VOICE_COMMAND = 7;
+
+    // Transcribe speech to text to create a written document, such as a
+    // text-message, email or report.
+    DICTATION = 8;
+  }
+
+  // Enumerates the types of capture settings describing an audio file.
+  enum MicrophoneDistance {
+    // Audio type is not known.
+    MICROPHONE_DISTANCE_UNSPECIFIED = 0;
+
+    // The audio was captured from a closely placed microphone. Eg. phone,
+    // dictaphone, or handheld microphone. Generally if there speaker is within
+    // 1 meter of the microphone.
+    NEARFIELD = 1;
+
+    // The speaker if within 3 meters of the microphone.
+    MIDFIELD = 2;
+
+    // The speaker is more than 3 meters away from the microphone.
+    FARFIELD = 3;
+  }
+
+  // The original media the speech was recorded on.
+  enum OriginalMediaType {
+    // Unknown original media type.
+    ORIGINAL_MEDIA_TYPE_UNSPECIFIED = 0;
+
+    // The speech data is an audio recording.
+    AUDIO = 1;
+
+    // The speech data originally recorded on a video.
+    VIDEO = 2;
+  }
+
+  // The type of device the speech was recorded with.
+  enum RecordingDeviceType {
+    // The recording device is unknown.
+    RECORDING_DEVICE_TYPE_UNSPECIFIED = 0;
+
+    // Speech was recorded on a smartphone.
+    SMARTPHONE = 1;
+
+    // Speech was recorded using a personal computer or tablet.
+    PC = 2;
+
+    // Speech was recorded over a phone line.
+    PHONE_LINE = 3;
+
+    // Speech was recorded in a vehicle.
+    VEHICLE = 4;
+
+    // Speech was recorded outdoors.
+    OTHER_OUTDOOR_DEVICE = 5;
+
+    // Speech was recorded indoors.
+    OTHER_INDOOR_DEVICE = 6;
+  }
+
+  // The use case most closely describing the audio content to be recognized.
+  InteractionType interaction_type = 1;
+
+  // The industry vertical to which this speech recognition request most
+  // closely applies. This is most indicative of the topics contained
+  // in the audio.  Use the 6-digit NAICS code to identify the industry
+  // vertical - see https://www.naics.com/search/.
+  uint32 industry_naics_code_of_audio = 3;
+
+  // The audio type that most closely describes the audio being recognized.
+  MicrophoneDistance microphone_distance = 4;
+
+  // The original media the speech was recorded on.
+  OriginalMediaType original_media_type = 5;
+
+  // The type of device the speech was recorded with.
+  RecordingDeviceType recording_device_type = 6;
+
+  // The device used to make the recording.  Examples 'Nexus 5X' or
+  // 'Polycom SoundStation IP 6000' or 'POTS' or 'VoIP' or
+  // 'Cardioid Microphone'.
+  string recording_device_name = 7;
+
+  // Mime type of the original audio file.  For example `audio/m4a`,
+  // `audio/x-alaw-basic`, `audio/mp3`, `audio/3gpp`.
+  // A list of possible audio mime types is maintained at
+  // http://www.iana.org/assignments/media-types/media-types.xhtml#audio
+  string original_mime_type = 8;
+
+  // Obfuscated (privacy-protected) ID of the user, to identify number of
+  // unique users using the service.
+  int64 obfuscated_id = 9;
+
+  // Description of the content. Eg. "Recordings of federal supreme court
+  // hearings from 2012".
+  string audio_topic = 10;
+}
+
+// Provides "hints" to the speech recognizer to favor specific words and phrases
+// in the results.
+message SpeechContext {
+  // *Optional* A list of strings containing words and phrases "hints" so that
+  // the speech recognition is more likely to recognize them. This can be used
+  // to improve the accuracy for specific words and phrases, for example, if
+  // specific commands are typically spoken by the user. This can also be used
+  // to add additional words to the vocabulary of the recognizer. See
+  // [usage limits](/speech-to-text/quotas#content).
+  repeated string phrases = 1;
+}
+
+// Contains audio data in the encoding specified in the `RecognitionConfig`.
+// Either `content` or `uri` must be supplied. Supplying both or neither
+// returns [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]. See
+// [content limits](/speech-to-text/quotas#content).
+message RecognitionAudio {
+  // The audio source, which is either inline content or a Google Cloud
+  // Storage uri.
+  oneof audio_source {
+    // The audio data bytes encoded as specified in
+    // `RecognitionConfig`. Note: as with all bytes fields, protobuffers use a
+    // pure binary representation, whereas JSON representations use base64.
+    bytes content = 1;
+
+    // URI that points to a file that contains audio data bytes as specified in
+    // `RecognitionConfig`. The file must not be compressed (for example, gzip).
+    // Currently, only Google Cloud Storage URIs are
+    // supported, which must be specified in the following format:
+    // `gs://bucket_name/object_name` (other URI formats return
+    // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+    // [Request URIs](https://cloud.google.com/storage/docs/reference-uris).
+    string uri = 2;
+  }
+}
+
+// The only message returned to the client by the `Recognize` method. It
+// contains the result as zero or more sequential `SpeechRecognitionResult`
+// messages.
+message RecognizeResponse {
+  // Output only. Sequential list of transcription results corresponding to
+  // sequential portions of audio.
+  repeated SpeechRecognitionResult results = 2;
+}
+
+// The only message returned to the client by the `LongRunningRecognize` method.
+// It contains the result as zero or more sequential `SpeechRecognitionResult`
+// messages. It is included in the `result.response` field of the `Operation`
+// returned by the `GetOperation` call of the `google::longrunning::Operations`
+// service.
+message LongRunningRecognizeResponse {
+  // Output only. Sequential list of transcription results corresponding to
+  // sequential portions of audio.
+  repeated SpeechRecognitionResult results = 2;
+}
+
+// Describes the progress of a long-running `LongRunningRecognize` call. It is
+// included in the `metadata` field of the `Operation` returned by the
+// `GetOperation` call of the `google::longrunning::Operations` service.
+message LongRunningRecognizeMetadata {
+  // Approximate percentage of audio processed thus far. Guaranteed to be 100
+  // when the audio is fully processed and the results are available.
+  int32 progress_percent = 1;
+
+  // Time when the request was received.
+  google.protobuf.Timestamp start_time = 2;
+
+  // Time of the most recent processing update.
+  google.protobuf.Timestamp last_update_time = 3;
+}
+
+// `StreamingRecognizeResponse` is the only message returned to the client by
+// `StreamingRecognize`. A series of zero or more `StreamingRecognizeResponse`
+// messages are streamed back to the client. If there is no recognizable
+// audio, and `single_utterance` is set to false, then no messages are streamed
+// back to the client.
+//
+// Here's an example of a series of ten `StreamingRecognizeResponse`s that might
+// be returned while processing audio:
+//
+// 1. results { alternatives { transcript: "tube" } stability: 0.01 }
+//
+// 2. results { alternatives { transcript: "to be a" } stability: 0.01 }
+//
+// 3. results { alternatives { transcript: "to be" } stability: 0.9 }
+//    results { alternatives { transcript: " or not to be" } stability: 0.01 }
+//
+// 4. results { alternatives { transcript: "to be or not to be"
+//                             confidence: 0.92 }
+//              alternatives { transcript: "to bee or not to bee" }
+//              is_final: true }
+//
+// 5. results { alternatives { transcript: " that's" } stability: 0.01 }
+//
+// 6. results { alternatives { transcript: " that is" } stability: 0.9 }
+//    results { alternatives { transcript: " the question" } stability: 0.01 }
+//
+// 7. results { alternatives { transcript: " that is the question"
+//                             confidence: 0.98 }
+//              alternatives { transcript: " that was the question" }
+//              is_final: true }
+//
+// Notes:
+//
+// - Only two of the above responses #4 and #7 contain final results; they are
+//   indicated by `is_final: true`. Concatenating these together generates the
+//   full transcript: "to be or not to be that is the question".
+//
+// - The others contain interim `results`. #3 and #6 contain two interim
+//   `results`: the first portion has a high stability and is less likely to
+//   change; the second portion has a low stability and is very likely to
+//   change. A UI designer might choose to show only high stability `results`.
+//
+// - The specific `stability` and `confidence` values shown above are only for
+//   illustrative purposes. Actual values may vary.
+//
+// - In each response, only one of these fields will be set:
+//     `error`,
+//     `speech_event_type`, or
+//     one or more (repeated) `results`.
+message StreamingRecognizeResponse {
+  // Indicates the type of speech event.
+  enum SpeechEventType {
+    // No speech event specified.
+    SPEECH_EVENT_UNSPECIFIED = 0;
+
+    // This event indicates that the server has detected the end of the user's
+    // speech utterance and expects no additional speech. Therefore, the server
+    // will not process additional audio (although it may subsequently return
+    // additional results). The client should stop sending additional audio
+    // data, half-close the gRPC connection, and wait for any additional results
+    // until the server closes the gRPC connection. This event is only sent if
+    // `single_utterance` was set to `true`, and is not used otherwise.
+    END_OF_SINGLE_UTTERANCE = 1;
+  }
+
+  // Output only. If set, returns a [google.rpc.Status][google.rpc.Status] message that
+  // specifies the error for the operation.
+  google.rpc.Status error = 1;
+
+  // Output only. This repeated list contains zero or more results that
+  // correspond to consecutive portions of the audio currently being processed.
+  // It contains zero or one `is_final=true` result (the newly settled portion),
+  // followed by zero or more `is_final=false` results (the interim results).
+  repeated StreamingRecognitionResult results = 2;
+
+  // Output only. Indicates the type of speech event.
+  SpeechEventType speech_event_type = 4;
+}
+
+// A streaming speech recognition result corresponding to a portion of the audio
+// that is currently being processed.
+message StreamingRecognitionResult {
+  // Output only. May contain one or more recognition hypotheses (up to the
+  // maximum specified in `max_alternatives`).
+  // These alternatives are ordered in terms of accuracy, with the top (first)
+  // alternative being the most probable, as ranked by the recognizer.
+  repeated SpeechRecognitionAlternative alternatives = 1;
+
+  // Output only. If `false`, this `StreamingRecognitionResult` represents an
+  // interim result that may change. If `true`, this is the final time the
+  // speech service will return this particular `StreamingRecognitionResult`,
+  // the recognizer will not return any further hypotheses for this portion of
+  // the transcript and corresponding audio.
+  bool is_final = 2;
+
+  // Output only. An estimate of the likelihood that the recognizer will not
+  // change its guess about this interim result. Values range from 0.0
+  // (completely unstable) to 1.0 (completely stable).
+  // This field is only provided for interim results (`is_final=false`).
+  // The default of 0.0 is a sentinel value indicating `stability` was not set.
+  float stability = 3;
+
+  // Output only. Time offset of the end of this result relative to the
+  // beginning of the audio.
+  google.protobuf.Duration result_end_time = 4;
+
+  // For multi-channel audio, this is the channel number corresponding to the
+  // recognized result for the audio from that channel.
+  // For audio_channel_count = N, its output values can range from '1' to 'N'.
+  int32 channel_tag = 5;
+
+  // Output only. The
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag of the
+  // language in this result. This language code was detected to have the most
+  // likelihood of being spoken in the audio.
+  string language_code = 6;
+}
+
+// A speech recognition result corresponding to a portion of the audio.
+message SpeechRecognitionResult {
+  // Output only. May contain one or more recognition hypotheses (up to the
+  // maximum specified in `max_alternatives`).
+  // These alternatives are ordered in terms of accuracy, with the top (first)
+  // alternative being the most probable, as ranked by the recognizer.
+  repeated SpeechRecognitionAlternative alternatives = 1;
+
+  // For multi-channel audio, this is the channel number corresponding to the
+  // recognized result for the audio from that channel.
+  // For audio_channel_count = N, its output values can range from '1' to 'N'.
+  int32 channel_tag = 2;
+
+  // Output only. The
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag of the
+  // language in this result. This language code was detected to have the most
+  // likelihood of being spoken in the audio.
+  string language_code = 5;
+}
+
+// Alternative hypotheses (a.k.a. n-best list).
+message SpeechRecognitionAlternative {
+  // Output only. Transcript text representing the words that the user spoke.
+  string transcript = 1;
+
+  // Output only. The confidence estimate between 0.0 and 1.0. A higher number
+  // indicates an estimated greater likelihood that the recognized words are
+  // correct. This field is set only for the top alternative of a non-streaming
+  // result or, of a streaming result where `is_final=true`.
+  // This field is not guaranteed to be accurate and users should not rely on it
+  // to be always provided.
+  // The default of 0.0 is a sentinel value indicating `confidence` was not set.
+  float confidence = 2;
+
+  // Output only. A list of word-specific information for each recognized word.
+  // Note: When `enable_speaker_diarization` is true, you will see all the words
+  // from the beginning of the audio.
+  repeated WordInfo words = 3;
+}
+
+// Word-specific information for recognized words.
+message WordInfo {
+  // Output only. Time offset relative to the beginning of the audio,
+  // and corresponding to the start of the spoken word.
+  // This field is only set if `enable_word_time_offsets=true` and only
+  // in the top hypothesis.
+  // This is an experimental feature and the accuracy of the time offset can
+  // vary.
+  google.protobuf.Duration start_time = 1;
+
+  // Output only. Time offset relative to the beginning of the audio,
+  // and corresponding to the end of the spoken word.
+  // This field is only set if `enable_word_time_offsets=true` and only
+  // in the top hypothesis.
+  // This is an experimental feature and the accuracy of the time offset can
+  // vary.
+  google.protobuf.Duration end_time = 2;
+
+  // Output only. The word corresponding to this set of information.
+  string word = 3;
+
+  // Output only. The confidence estimate between 0.0 and 1.0. A higher number
+  // indicates an estimated greater likelihood that the recognized words are
+  // correct. This field is set only for the top alternative of a non-streaming
+  // result or, of a streaming result where `is_final=true`.
+  // This field is not guaranteed to be accurate and users should not rely on it
+  // to be always provided.
+  // The default of 0.0 is a sentinel value indicating `confidence` was not set.
+  float confidence = 4;
+
+  // Output only. A distinct integer value is assigned for every speaker within
+  // the audio. This field specifies which one of those speakers was detected to
+  // have spoken this word. Value ranges from '1' to diarization_speaker_count.
+  // speaker_tag is set if enable_speaker_diarization = 'true' and only in the
+  // top alternative.
+  int32 speaker_tag = 5;
+}
diff --git a/speech/google/cloud/speech_v1p1beta1/proto/cloud_speech_pb2.py b/speech/google/cloud/speech_v1p1beta1/proto/cloud_speech_pb2.py
index c466e71cb8dc..78aa8e57683e 100644
--- a/speech/google/cloud/speech_v1p1beta1/proto/cloud_speech_pb2.py
+++ b/speech/google/cloud/speech_v1p1beta1/proto/cloud_speech_pb2.py
@@ -2649,3 +2649,4 @@
 DESCRIPTOR.services_by_name["Speech"] = _SPEECH
 
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/speech/synth.metadata b/speech/synth.metadata
index d35aa99a26a8..ff006e1aa2c4 100644
--- a/speech/synth.metadata
+++ b/speech/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:28:15.149724Z",
+  "updateTime": "2019-01-24T17:33:42.993903Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/speech/synth.py b/speech/synth.py
index d28372d6b3a5..162248a005aa 100644
--- a/speech/synth.py
+++ b/speech/synth.py
@@ -28,7 +28,7 @@
 # Generate speech GAPIC layer
 # ----------------------------------------------------------------------------
 for version in versions:
-    library = gapic.py_library("speech", version)
+    library = gapic.py_library("speech", version, include_protos=True,)
 
     # Don't move over __init__.py, as we modify it to make the generated client
     # use helpers.py.
diff --git a/tasks/google/cloud/tasks_v2beta2/proto/cloudtasks.proto b/tasks/google/cloud/tasks_v2beta2/proto/cloudtasks.proto
new file mode 100644
index 000000000000..fcdd9cf9e558
--- /dev/null
+++ b/tasks/google/cloud/tasks_v2beta2/proto/cloudtasks.proto
@@ -0,0 +1,600 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.tasks.v2beta3;
+
+import "google/api/annotations.proto";
+import "google/cloud/tasks/v2beta3/queue.proto";
+import "google/cloud/tasks/v2beta3/task.proto";
+import "google/iam/v1/iam_policy.proto";
+import "google/iam/v1/policy.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/rpc/code.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3;tasks";
+option java_multiple_files = true;
+option java_outer_classname = "CloudTasksProto";
+option java_package = "com.google.cloud.tasks.v2beta3";
+option objc_class_prefix = "TASKS";
+
+
+// Cloud Tasks allows developers to manage the execution of background
+// work in their applications.
+service CloudTasks {
+  // Lists queues.
+  //
+  // Queues are returned in lexicographical order.
+  rpc ListQueues(ListQueuesRequest) returns (ListQueuesResponse) {
+    option (google.api.http) = {
+      get: "/v2beta3/{parent=projects/*/locations/*}/queues"
+    };
+  }
+
+  // Gets a queue.
+  rpc GetQueue(GetQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      get: "/v2beta3/{name=projects/*/locations/*/queues/*}"
+    };
+  }
+
+  // Creates a queue.
+  //
+  // Queues created with this method allow tasks to live for a maximum of 31
+  // days. After a task is 31 days old, the task will be deleted regardless of whether
+  // it was dispatched or not.
+  //
+  // WARNING: Using this method may have unintended side effects if you are
+  // using an App Engine `queue.yaml` or `queue.xml` file to manage your queues.
+  // Read
+  // [Overview of Queue Management and queue.yaml](https://cloud.google.com/tasks/docs/queue-yaml)
+  // before using this method.
+  rpc CreateQueue(CreateQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      post: "/v2beta3/{parent=projects/*/locations/*}/queues"
+      body: "queue"
+    };
+  }
+
+  // Updates a queue.
+  //
+  // This method creates the queue if it does not exist and updates
+  // the queue if it does exist.
+  //
+  // Queues created with this method allow tasks to live for a maximum of 31
+  // days. After a task is 31 days old, the task will be deleted regardless of whether
+  // it was dispatched or not.
+  //
+  // WARNING: Using this method may have unintended side effects if you are
+  // using an App Engine `queue.yaml` or `queue.xml` file to manage your queues.
+  // Read
+  // [Overview of Queue Management and queue.yaml](https://cloud.google.com/tasks/docs/queue-yaml)
+  // before using this method.
+  rpc UpdateQueue(UpdateQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      patch: "/v2beta3/{queue.name=projects/*/locations/*/queues/*}"
+      body: "queue"
+    };
+  }
+
+  // Deletes a queue.
+  //
+  // This command will delete the queue even if it has tasks in it.
+  //
+  // Note: If you delete a queue, a queue with the same name can't be created
+  // for 7 days.
+  //
+  // WARNING: Using this method may have unintended side effects if you are
+  // using an App Engine `queue.yaml` or `queue.xml` file to manage your queues.
+  // Read
+  // [Overview of Queue Management and queue.yaml](https://cloud.google.com/tasks/docs/queue-yaml)
+  // before using this method.
+  rpc DeleteQueue(DeleteQueueRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2beta3/{name=projects/*/locations/*/queues/*}"
+    };
+  }
+
+  // Purges a queue by deleting all of its tasks.
+  //
+  // All tasks created before this method is called are permanently deleted.
+  //
+  // Purge operations can take up to one minute to take effect. Tasks
+  // might be dispatched before the purge takes effect. A purge is irreversible.
+  rpc PurgeQueue(PurgeQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      post: "/v2beta3/{name=projects/*/locations/*/queues/*}:purge"
+      body: "*"
+    };
+  }
+
+  // Pauses the queue.
+  //
+  // If a queue is paused then the system will stop dispatching tasks
+  // until the queue is resumed via
+  // [ResumeQueue][google.cloud.tasks.v2beta3.CloudTasks.ResumeQueue]. Tasks can still be added
+  // when the queue is paused. A queue is paused if its
+  // [state][google.cloud.tasks.v2beta3.Queue.state] is [PAUSED][google.cloud.tasks.v2beta3.Queue.State.PAUSED].
+  rpc PauseQueue(PauseQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      post: "/v2beta3/{name=projects/*/locations/*/queues/*}:pause"
+      body: "*"
+    };
+  }
+
+  // Resume a queue.
+  //
+  // This method resumes a queue after it has been
+  // [PAUSED][google.cloud.tasks.v2beta3.Queue.State.PAUSED] or
+  // [DISABLED][google.cloud.tasks.v2beta3.Queue.State.DISABLED]. The state of a queue is stored
+  // in the queue's [state][google.cloud.tasks.v2beta3.Queue.state]; after calling this method it
+  // will be set to [RUNNING][google.cloud.tasks.v2beta3.Queue.State.RUNNING].
+  //
+  // WARNING: Resuming many high-QPS queues at the same time can
+  // lead to target overloading. If you are resuming high-QPS
+  // queues, follow the 500/50/5 pattern described in
+  // [Managing Cloud Tasks Scaling Risks](https://cloud.google.com/tasks/docs/manage-cloud-task-scaling).
+  rpc ResumeQueue(ResumeQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      post: "/v2beta3/{name=projects/*/locations/*/queues/*}:resume"
+      body: "*"
+    };
+  }
+
+  // Gets the access control policy for a [Queue][google.cloud.tasks.v2beta3.Queue].
+  // Returns an empty policy if the resource exists and does not have a policy
+  // set.
+  //
+  // Authorization requires the following
+  // [Google IAM](https://cloud.google.com/iam) permission on the specified
+  // resource parent:
+  //
+  // * `cloudtasks.queues.getIamPolicy`
+  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v2beta3/{resource=projects/*/locations/*/queues/*}:getIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Sets the access control policy for a [Queue][google.cloud.tasks.v2beta3.Queue]. Replaces any existing
+  // policy.
+  //
+  // Note: The Cloud Console does not check queue-level IAM permissions yet.
+  // Project-level permissions are required to use the Cloud Console.
+  //
+  // Authorization requires the following
+  // [Google IAM](https://cloud.google.com/iam) permission on the specified
+  // resource parent:
+  //
+  // * `cloudtasks.queues.setIamPolicy`
+  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v2beta3/{resource=projects/*/locations/*/queues/*}:setIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Returns permissions that a caller has on a [Queue][google.cloud.tasks.v2beta3.Queue].
+  // If the resource does not exist, this will return an empty set of
+  // permissions, not a [NOT_FOUND][google.rpc.Code.NOT_FOUND] error.
+  //
+  // Note: This operation is designed to be used for building permission-aware
+  // UIs and command-line tools, not for authorization checking. This operation
+  // may "fail open" without warning.
+  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) {
+    option (google.api.http) = {
+      post: "/v2beta3/{resource=projects/*/locations/*/queues/*}:testIamPermissions"
+      body: "*"
+    };
+  }
+
+  // Lists the tasks in a queue.
+  //
+  // By default, only the [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC] view is retrieved
+  // due to performance considerations;
+  // [response_view][google.cloud.tasks.v2beta3.ListTasksRequest.response_view] controls the
+  // subset of information which is returned.
+  //
+  // The tasks may be returned in any order. The ordering may change at any
+  // time.
+  rpc ListTasks(ListTasksRequest) returns (ListTasksResponse) {
+    option (google.api.http) = {
+      get: "/v2beta3/{parent=projects/*/locations/*/queues/*}/tasks"
+    };
+  }
+
+  // Gets a task.
+  rpc GetTask(GetTaskRequest) returns (Task) {
+    option (google.api.http) = {
+      get: "/v2beta3/{name=projects/*/locations/*/queues/*/tasks/*}"
+    };
+  }
+
+  // Creates a task and adds it to a queue.
+  //
+  // Tasks cannot be updated after creation; there is no UpdateTask command.
+  //
+  // * For [App Engine queues][google.cloud.tasks.v2beta3.AppEngineHttpQueue], the maximum task size is
+  //   100KB.
+  rpc CreateTask(CreateTaskRequest) returns (Task) {
+    option (google.api.http) = {
+      post: "/v2beta3/{parent=projects/*/locations/*/queues/*}/tasks"
+      body: "*"
+    };
+  }
+
+  // Deletes a task.
+  //
+  // A task can be deleted if it is scheduled or dispatched. A task
+  // cannot be deleted if it has executed successfully or permanently
+  // failed.
+  rpc DeleteTask(DeleteTaskRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2beta3/{name=projects/*/locations/*/queues/*/tasks/*}"
+    };
+  }
+
+  // Forces a task to run now.
+  //
+  // When this method is called, Cloud Tasks will dispatch the task, even if
+  // the task is already running, the queue has reached its [RateLimits][google.cloud.tasks.v2beta3.RateLimits] or
+  // is [PAUSED][google.cloud.tasks.v2beta3.Queue.State.PAUSED].
+  //
+  // This command is meant to be used for manual debugging. For
+  // example, [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask] can be used to retry a failed
+  // task after a fix has been made or to manually force a task to be
+  // dispatched now.
+  //
+  // The dispatched task is returned. That is, the task that is returned
+  // contains the [status][Task.status] after the task is dispatched but
+  // before the task is received by its target.
+  //
+  // If Cloud Tasks receives a successful response from the task's
+  // target, then the task will be deleted; otherwise the task's
+  // [schedule_time][google.cloud.tasks.v2beta3.Task.schedule_time] will be reset to the time that
+  // [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask] was called plus the retry delay specified
+  // in the queue's [RetryConfig][google.cloud.tasks.v2beta3.RetryConfig].
+  //
+  // [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask] returns
+  // [NOT_FOUND][google.rpc.Code.NOT_FOUND] when it is called on a
+  // task that has already succeeded or permanently failed.
+  rpc RunTask(RunTaskRequest) returns (Task) {
+    option (google.api.http) = {
+      post: "/v2beta3/{name=projects/*/locations/*/queues/*/tasks/*}:run"
+      body: "*"
+    };
+  }
+}
+
+// Request message for [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues].
+message ListQueuesRequest {
+  // Required.
+  //
+  // The location name.
+  // For example: `projects/PROJECT_ID/locations/LOCATION_ID`
+  string parent = 1;
+
+  // `filter` can be used to specify a subset of queues. Any [Queue][google.cloud.tasks.v2beta3.Queue]
+  // field can be used as a filter and several operators as supported.
+  // For example: `<=, <, >=, >, !=, =, :`. The filter syntax is the same as
+  // described in
+  // [Stackdriver's Advanced Logs Filters](https://cloud.google.com/logging/docs/view/advanced_filters).
+  //
+  // Sample filter "state: PAUSED".
+  //
+  // Note that using filters might cause fewer queues than the
+  // requested page_size to be returned.
+  string filter = 2;
+
+  // Requested page size.
+  //
+  // The maximum page size is 9800. If unspecified, the page size will
+  // be the maximum. Fewer queues than requested might be returned,
+  // even if more queues exist; use the
+  // [next_page_token][google.cloud.tasks.v2beta3.ListQueuesResponse.next_page_token] in the
+  // response to determine if more queues exist.
+  int32 page_size = 3;
+
+  // A token identifying the page of results to return.
+  //
+  // To request the first page results, page_token must be empty. To
+  // request the next page of results, page_token must be the value of
+  // [next_page_token][google.cloud.tasks.v2beta3.ListQueuesResponse.next_page_token] returned
+  // from the previous call to [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues]
+  // method. It is an error to switch the value of the
+  // [filter][google.cloud.tasks.v2beta3.ListQueuesRequest.filter] while iterating through pages.
+  string page_token = 4;
+}
+
+// Response message for [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues].
+message ListQueuesResponse {
+  // The list of queues.
+  repeated Queue queues = 1;
+
+  // A token to retrieve next page of results.
+  //
+  // To return the next page of results, call
+  // [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues] with this value as the
+  // [page_token][google.cloud.tasks.v2beta3.ListQueuesRequest.page_token].
+  //
+  // If the next_page_token is empty, there are no more results.
+  //
+  // The page token is valid for only 2 hours.
+  string next_page_token = 2;
+}
+
+// Request message for [GetQueue][google.cloud.tasks.v2beta3.CloudTasks.GetQueue].
+message GetQueueRequest {
+  // Required.
+  //
+  // The resource name of the queue. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID`
+  string name = 1;
+}
+
+// Request message for [CreateQueue][google.cloud.tasks.v2beta3.CloudTasks.CreateQueue].
+message CreateQueueRequest {
+  // Required.
+  //
+  // The location name in which the queue will be created.
+  // For example: `projects/PROJECT_ID/locations/LOCATION_ID`
+  //
+  // The list of allowed locations can be obtained by calling Cloud
+  // Tasks' implementation of
+  // [ListLocations][google.cloud.location.Locations.ListLocations].
+  string parent = 1;
+
+  // Required.
+  //
+  // The queue to create.
+  //
+  // [Queue's name][google.cloud.tasks.v2beta3.Queue.name] cannot be the same as an existing queue.
+  Queue queue = 2;
+}
+
+// Request message for [UpdateQueue][google.cloud.tasks.v2beta3.CloudTasks.UpdateQueue].
+message UpdateQueueRequest {
+  // Required.
+  //
+  // The queue to create or update.
+  //
+  // The queue's [name][google.cloud.tasks.v2beta3.Queue.name] must be specified.
+  //
+  // Output only fields cannot be modified using UpdateQueue.
+  // Any value specified for an output only field will be ignored.
+  // The queue's [name][google.cloud.tasks.v2beta3.Queue.name] cannot be changed.
+  Queue queue = 1;
+
+  // A mask used to specify which fields of the queue are being updated.
+  //
+  // If empty, then all fields will be updated.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for [DeleteQueue][google.cloud.tasks.v2beta3.CloudTasks.DeleteQueue].
+message DeleteQueueRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID`
+  string name = 1;
+}
+
+// Request message for [PurgeQueue][google.cloud.tasks.v2beta3.CloudTasks.PurgeQueue].
+message PurgeQueueRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/location/LOCATION_ID/queues/QUEUE_ID`
+  string name = 1;
+}
+
+// Request message for [PauseQueue][google.cloud.tasks.v2beta3.CloudTasks.PauseQueue].
+message PauseQueueRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/location/LOCATION_ID/queues/QUEUE_ID`
+  string name = 1;
+}
+
+// Request message for [ResumeQueue][google.cloud.tasks.v2beta3.CloudTasks.ResumeQueue].
+message ResumeQueueRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/location/LOCATION_ID/queues/QUEUE_ID`
+  string name = 1;
+}
+
+// Request message for listing tasks using [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks].
+message ListTasksRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID`
+  string parent = 1;
+
+  // The response_view specifies which subset of the [Task][google.cloud.tasks.v2beta3.Task] will be
+  // returned.
+  //
+  // By default response_view is [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC]; not all
+  // information is retrieved by default because some data, such as
+  // payloads, might be desirable to return only when needed because
+  // of its large size or because of the sensitivity of data that it
+  // contains.
+  //
+  // Authorization for [FULL][google.cloud.tasks.v2beta3.Task.View.FULL] requires
+  // `cloudtasks.tasks.fullView` [Google IAM](https://cloud.google.com/iam/)
+  // permission on the [Task][google.cloud.tasks.v2beta3.Task] resource.
+  Task.View response_view = 2;
+
+  // Requested page size. Fewer tasks than requested might be returned.
+  //
+  // The maximum page size is 1000. If unspecified, the page size will
+  // be the maximum. Fewer tasks than requested might be returned,
+  // even if more tasks exist; use
+  // [next_page_token][google.cloud.tasks.v2beta3.ListTasksResponse.next_page_token] in the
+  // response to determine if more tasks exist.
+  int32 page_size = 3;
+
+  // A token identifying the page of results to return.
+  //
+  // To request the first page results, page_token must be empty. To
+  // request the next page of results, page_token must be the value of
+  // [next_page_token][google.cloud.tasks.v2beta3.ListTasksResponse.next_page_token] returned
+  // from the previous call to [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks]
+  // method.
+  //
+  // The page token is valid for only 2 hours.
+  string page_token = 4;
+}
+
+// Response message for listing tasks using [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks].
+message ListTasksResponse {
+  // The list of tasks.
+  repeated Task tasks = 1;
+
+  // A token to retrieve next page of results.
+  //
+  // To return the next page of results, call
+  // [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks] with this value as the
+  // [page_token][google.cloud.tasks.v2beta3.ListTasksRequest.page_token].
+  //
+  // If the next_page_token is empty, there are no more results.
+  string next_page_token = 2;
+}
+
+// Request message for getting a task using [GetTask][google.cloud.tasks.v2beta3.CloudTasks.GetTask].
+message GetTaskRequest {
+  // Required.
+  //
+  // The task name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID`
+  string name = 1;
+
+  // The response_view specifies which subset of the [Task][google.cloud.tasks.v2beta3.Task] will be
+  // returned.
+  //
+  // By default response_view is [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC]; not all
+  // information is retrieved by default because some data, such as
+  // payloads, might be desirable to return only when needed because
+  // of its large size or because of the sensitivity of data that it
+  // contains.
+  //
+  // Authorization for [FULL][google.cloud.tasks.v2beta3.Task.View.FULL] requires
+  // `cloudtasks.tasks.fullView` [Google IAM](https://cloud.google.com/iam/)
+  // permission on the [Task][google.cloud.tasks.v2beta3.Task] resource.
+  Task.View response_view = 2;
+}
+
+// Request message for [CreateTask][google.cloud.tasks.v2beta3.CloudTasks.CreateTask].
+message CreateTaskRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID`
+  //
+  // The queue must already exist.
+  string parent = 1;
+
+  // Required.
+  //
+  // The task to add.
+  //
+  // Task names have the following format:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID`.
+  // The user can optionally specify a task [name][google.cloud.tasks.v2beta3.Task.name]. If a
+  // name is not specified then the system will generate a random
+  // unique task id, which will be set in the task returned in the
+  // [response][google.cloud.tasks.v2beta3.Task.name].
+  //
+  // If [schedule_time][google.cloud.tasks.v2beta3.Task.schedule_time] is not set or is in the
+  // past then Cloud Tasks will set it to the current time.
+  //
+  // Task De-duplication:
+  //
+  // Explicitly specifying a task ID enables task de-duplication.  If
+  // a task's ID is identical to that of an existing task or a task
+  // that was deleted or executed recently then the call will fail
+  // with [ALREADY_EXISTS][google.rpc.Code.ALREADY_EXISTS].
+  // If the task's queue was created using Cloud Tasks, then another task with
+  // the same name can't be created for ~1hour after the original task was
+  // deleted or executed. If the task's queue was created using queue.yaml or
+  // queue.xml, then another task with the same name can't be created
+  // for ~9days after the original task was deleted or executed.
+  //
+  // Because there is an extra lookup cost to identify duplicate task
+  // names, these [CreateTask][google.cloud.tasks.v2beta3.CloudTasks.CreateTask] calls have significantly
+  // increased latency. Using hashed strings for the task id or for
+  // the prefix of the task id is recommended. Choosing task ids that
+  // are sequential or have sequential prefixes, for example using a
+  // timestamp, causes an increase in latency and error rates in all
+  // task commands. The infrastructure relies on an approximately
+  // uniform distribution of task ids to store and serve tasks
+  // efficiently.
+  Task task = 2;
+
+  // The response_view specifies which subset of the [Task][google.cloud.tasks.v2beta3.Task] will be
+  // returned.
+  //
+  // By default response_view is [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC]; not all
+  // information is retrieved by default because some data, such as
+  // payloads, might be desirable to return only when needed because
+  // of its large size or because of the sensitivity of data that it
+  // contains.
+  //
+  // Authorization for [FULL][google.cloud.tasks.v2beta3.Task.View.FULL] requires
+  // `cloudtasks.tasks.fullView` [Google IAM](https://cloud.google.com/iam/)
+  // permission on the [Task][google.cloud.tasks.v2beta3.Task] resource.
+  Task.View response_view = 3;
+}
+
+// Request message for deleting a task using
+// [DeleteTask][google.cloud.tasks.v2beta3.CloudTasks.DeleteTask].
+message DeleteTaskRequest {
+  // Required.
+  //
+  // The task name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID`
+  string name = 1;
+}
+
+// Request message for forcing a task to run now using
+// [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask].
+message RunTaskRequest {
+  // Required.
+  //
+  // The task name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID`
+  string name = 1;
+
+  // The response_view specifies which subset of the [Task][google.cloud.tasks.v2beta3.Task] will be
+  // returned.
+  //
+  // By default response_view is [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC]; not all
+  // information is retrieved by default because some data, such as
+  // payloads, might be desirable to return only when needed because
+  // of its large size or because of the sensitivity of data that it
+  // contains.
+  //
+  // Authorization for [FULL][google.cloud.tasks.v2beta3.Task.View.FULL] requires
+  // `cloudtasks.tasks.fullView` [Google IAM](https://cloud.google.com/iam/)
+  // permission on the [Task][google.cloud.tasks.v2beta3.Task] resource.
+  Task.View response_view = 2;
+}
diff --git a/tasks/google/cloud/tasks_v2beta2/proto/queue.proto b/tasks/google/cloud/tasks_v2beta2/proto/queue.proto
new file mode 100644
index 000000000000..4b6b92663651
--- /dev/null
+++ b/tasks/google/cloud/tasks_v2beta2/proto/queue.proto
@@ -0,0 +1,326 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.tasks.v2beta3;
+
+import "google/api/annotations.proto";
+import "google/cloud/tasks/v2beta3/target.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3;tasks";
+option java_multiple_files = true;
+option java_outer_classname = "QueueProto";
+option java_package = "com.google.cloud.tasks.v2beta3";
+
+
+// A queue is a container of related tasks. Queues are configured to manage
+// how those tasks are dispatched. Configurable properties include rate limits,
+// retry options, queue types, and others.
+message Queue {
+  // State of the queue.
+  enum State {
+    // Unspecified state.
+    STATE_UNSPECIFIED = 0;
+
+    // The queue is running. Tasks can be dispatched.
+    //
+    // If the queue was created using Cloud Tasks and the queue has
+    // had no activity (method calls or task dispatches) for 30 days,
+    // the queue may take a few minutes to re-activate. Some method
+    // calls may return [NOT_FOUND][google.rpc.Code.NOT_FOUND] and
+    // tasks may not be dispatched for a few minutes until the queue
+    // has been re-activated.
+    RUNNING = 1;
+
+    // Tasks are paused by the user. If the queue is paused then Cloud
+    // Tasks will stop delivering tasks from it, but more tasks can
+    // still be added to it by the user.
+    PAUSED = 2;
+
+    // The queue is disabled.
+    //
+    // A queue becomes `DISABLED` when
+    // [queue.yaml](https://cloud.google.com/appengine/docs/python/config/queueref)
+    // or
+    // [queue.xml](https://cloud.google.com/appengine/docs/standard/java/config/queueref)
+    // is uploaded which does not contain the queue. You cannot directly disable
+    // a queue.
+    //
+    // When a queue is disabled, tasks can still be added to a queue
+    // but the tasks are not dispatched.
+    //
+    // To permanently delete this queue and all of its tasks, call
+    // [DeleteQueue][google.cloud.tasks.v2beta3.CloudTasks.DeleteQueue].
+    DISABLED = 3;
+  }
+
+  // Caller-specified and required in [CreateQueue][google.cloud.tasks.v2beta3.CloudTasks.CreateQueue],
+  // after which it becomes output only.
+  //
+  // The queue name.
+  //
+  // The queue name must have the following format:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID`
+  //
+  // * `PROJECT_ID` can contain letters ([A-Za-z]), numbers ([0-9]),
+  //    hyphens (-), colons (:), or periods (.).
+  //    For more information, see
+  //    [Identifying projects](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects)
+  // * `LOCATION_ID` is the canonical ID for the queue's location.
+  //    The list of available locations can be obtained by calling
+  //    [ListLocations][google.cloud.location.Locations.ListLocations].
+  //    For more information, see https://cloud.google.com/about/locations/.
+  // * `QUEUE_ID` can contain letters ([A-Za-z]), numbers ([0-9]), or
+  //   hyphens (-). The maximum length is 100 characters.
+  string name = 1;
+
+  oneof queue_type {
+    // [AppEngineHttpQueue][google.cloud.tasks.v2beta3.AppEngineHttpQueue] settings apply only to
+    // [App Engine tasks][google.cloud.tasks.v2beta3.AppEngineHttpRequest] in this queue.
+    AppEngineHttpQueue app_engine_http_queue = 3;
+  }
+
+  // Rate limits for task dispatches.
+  //
+  // [rate_limits][google.cloud.tasks.v2beta3.Queue.rate_limits] and [retry_config][google.cloud.tasks.v2beta3.Queue.retry_config] are
+  // related because they both control task attempts. However they control task
+  // attempts in different ways:
+  //
+  // * [rate_limits][google.cloud.tasks.v2beta3.Queue.rate_limits] controls the total rate of
+  //   dispatches from a queue (i.e. all traffic dispatched from the
+  //   queue, regardless of whether the dispatch is from a first
+  //   attempt or a retry).
+  // * [retry_config][google.cloud.tasks.v2beta3.Queue.retry_config] controls what happens to
+  //   particular a task after its first attempt fails. That is,
+  //   [retry_config][google.cloud.tasks.v2beta3.Queue.retry_config] controls task retries (the
+  //   second attempt, third attempt, etc).
+  //
+  // The queue's actual dispatch rate is the result of:
+  //
+  // * Number of tasks in the queue
+  // * User-specified throttling: [rate limits][Queue.RateLimits]
+  //   [retry configuration][Queue.RetryConfig], and the
+  //   [queue's state][google.cloud.tasks.v2beta3.Queue.state].
+  // * System throttling due to `429` (Too Many Requests) or `503` (Service
+  //   Unavailable) responses from the worker, high error rates, or to smooth
+  //   sudden large traffic spikes.
+  RateLimits rate_limits = 4;
+
+  // Settings that determine the retry behavior.
+  //
+  // * For tasks created using Cloud Tasks: the queue-level retry settings
+  //   apply to all tasks in the queue that were created using Cloud Tasks.
+  //   Retry settings cannot be set on individual tasks.
+  // * For tasks created using the App Engine SDK: the queue-level retry
+  //   settings apply to all tasks in the queue which do not have retry settings
+  //   explicitly set on the task and were created by the App Engine SDK. See
+  //   [App Engine documentation](https://cloud.google.com/appengine/docs/standard/python/taskqueue/push/retrying-tasks).
+  RetryConfig retry_config = 5;
+
+  // Output only. The state of the queue.
+  //
+  // `state` can only be changed by called
+  // [PauseQueue][google.cloud.tasks.v2beta3.CloudTasks.PauseQueue],
+  // [ResumeQueue][google.cloud.tasks.v2beta3.CloudTasks.ResumeQueue], or uploading
+  // [queue.yaml/xml](https://cloud.google.com/appengine/docs/python/config/queueref).
+  // [UpdateQueue][google.cloud.tasks.v2beta3.CloudTasks.UpdateQueue] cannot be used to change `state`.
+  State state = 6;
+
+  // Output only. The last time this queue was purged.
+  //
+  // All tasks that were [created][google.cloud.tasks.v2beta3.Task.create_time] before this time
+  // were purged.
+  //
+  // A queue can be purged using [PurgeQueue][google.cloud.tasks.v2beta3.CloudTasks.PurgeQueue], the
+  // [App Engine Task Queue SDK, or the Cloud Console](https://cloud.google.com/appengine/docs/standard/python/taskqueue/push/deleting-tasks-and-queues#purging_all_tasks_from_a_queue).
+  //
+  // Purge time will be truncated to the nearest microsecond. Purge
+  // time will be unset if the queue has never been purged.
+  google.protobuf.Timestamp purge_time = 7;
+}
+
+// Rate limits.
+//
+// This message determines the maximum rate that tasks can be dispatched by a
+// queue, regardless of whether the dispatch is a first task attempt or a retry.
+//
+// Note: The debugging command, [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask], will run a task
+// even if the queue has reached its [RateLimits][google.cloud.tasks.v2beta3.RateLimits].
+message RateLimits {
+  // The maximum rate at which tasks are dispatched from this queue.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  // * For [App Engine queues][google.cloud.tasks.v2beta3.AppEngineHttpQueue], the maximum allowed value
+  //   is 500.
+  //
+  //
+  // This field has the same meaning as
+  // [rate in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#rate).
+  double max_dispatches_per_second = 1;
+
+  // Output only. The max burst size.
+  //
+  // Max burst size limits how fast tasks in queue are processed when
+  // many tasks are in the queue and the rate is high. This field
+  // allows the queue to have a high rate so processing starts shortly
+  // after a task is enqueued, but still limits resource usage when
+  // many tasks are enqueued in a short period of time.
+  //
+  // The [token bucket](https://wikipedia.org/wiki/Token_Bucket)
+  // algorithm is used to control the rate of task dispatches. Each
+  // queue has a token bucket that holds tokens, up to the maximum
+  // specified by `max_burst_size`. Each time a task is dispatched, a
+  // token is removed from the bucket. Tasks will be dispatched until
+  // the queue's bucket runs out of tokens. The bucket will be
+  // continuously refilled with new tokens based on
+  // [max_dispatches_per_second][google.cloud.tasks.v2beta3.RateLimits.max_dispatches_per_second].
+  //
+  // Cloud Tasks will pick the value of `max_burst_size` based on the
+  // value of
+  // [max_dispatches_per_second][google.cloud.tasks.v2beta3.RateLimits.max_dispatches_per_second].
+  //
+  // For App Engine queues that were created or updated using
+  // `queue.yaml/xml`, `max_burst_size` is equal to
+  // [bucket_size](https://cloud.google.com/appengine/docs/standard/python/config/queueref#bucket_size).
+  // Since `max_burst_size` is output only, if
+  // [UpdateQueue][google.cloud.tasks.v2beta3.CloudTasks.UpdateQueue] is called on a queue
+  // created by `queue.yaml/xml`, `max_burst_size` will be reset based
+  // on the value of
+  // [max_dispatches_per_second][google.cloud.tasks.v2beta3.RateLimits.max_dispatches_per_second],
+  // regardless of whether
+  // [max_dispatches_per_second][google.cloud.tasks.v2beta3.RateLimits.max_dispatches_per_second]
+  // is updated.
+  //
+  int32 max_burst_size = 2;
+
+  // The maximum number of concurrent tasks that Cloud Tasks allows
+  // to be dispatched for this queue. After this threshold has been
+  // reached, Cloud Tasks stops dispatching tasks until the number of
+  // concurrent requests decreases.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  //
+  // The maximum allowed value is 5,000.
+  //
+  //
+  // This field has the same meaning as
+  // [max_concurrent_requests in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#max_concurrent_requests).
+  int32 max_concurrent_dispatches = 3;
+}
+
+// Retry config.
+//
+// These settings determine when a failed task attempt is retried.
+message RetryConfig {
+  // Number of attempts per task.
+  //
+  // Cloud Tasks will attempt the task `max_attempts` times (that is, if the
+  // first attempt fails, then there will be `max_attempts - 1` retries). Must
+  // be >= -1.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  // -1 indicates unlimited attempts.
+  //
+  // This field has the same meaning as
+  // [task_retry_limit in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#retry_parameters).
+  int32 max_attempts = 1;
+
+  // If positive, `max_retry_duration` specifies the time limit for
+  // retrying a failed task, measured from when the task was first
+  // attempted. Once `max_retry_duration` time has passed *and* the
+  // task has been attempted [max_attempts][google.cloud.tasks.v2beta3.RetryConfig.max_attempts]
+  // times, no further attempts will be made and the task will be
+  // deleted.
+  //
+  // If zero, then the task age is unlimited.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  //
+  // `max_retry_duration` will be truncated to the nearest second.
+  //
+  // This field has the same meaning as
+  // [task_age_limit in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#retry_parameters).
+  google.protobuf.Duration max_retry_duration = 2;
+
+  // A task will be [scheduled][google.cloud.tasks.v2beta3.Task.schedule_time] for retry between
+  // [min_backoff][google.cloud.tasks.v2beta3.RetryConfig.min_backoff] and
+  // [max_backoff][google.cloud.tasks.v2beta3.RetryConfig.max_backoff] duration after it fails,
+  // if the queue's [RetryConfig][google.cloud.tasks.v2beta3.RetryConfig] specifies that the task should be
+  // retried.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  //
+  // `min_backoff` will be truncated to the nearest second.
+  //
+  // This field has the same meaning as
+  // [min_backoff_seconds in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#retry_parameters).
+  google.protobuf.Duration min_backoff = 3;
+
+  // A task will be [scheduled][google.cloud.tasks.v2beta3.Task.schedule_time] for retry between
+  // [min_backoff][google.cloud.tasks.v2beta3.RetryConfig.min_backoff] and
+  // [max_backoff][google.cloud.tasks.v2beta3.RetryConfig.max_backoff] duration after it fails,
+  // if the queue's [RetryConfig][google.cloud.tasks.v2beta3.RetryConfig] specifies that the task should be
+  // retried.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  //
+  // `max_backoff` will be truncated to the nearest second.
+  //
+  // This field has the same meaning as
+  // [max_backoff_seconds in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#retry_parameters).
+  google.protobuf.Duration max_backoff = 4;
+
+  // The time between retries will double `max_doublings` times.
+  //
+  // A task's retry interval starts at
+  // [min_backoff][google.cloud.tasks.v2beta3.RetryConfig.min_backoff], then doubles
+  // `max_doublings` times, then increases linearly, and finally
+  // retries retries at intervals of
+  // [max_backoff][google.cloud.tasks.v2beta3.RetryConfig.max_backoff] up to
+  // [max_attempts][google.cloud.tasks.v2beta3.RetryConfig.max_attempts] times.
+  //
+  // For example, if [min_backoff][google.cloud.tasks.v2beta3.RetryConfig.min_backoff] is 10s,
+  // [max_backoff][google.cloud.tasks.v2beta3.RetryConfig.max_backoff] is 300s, and
+  // `max_doublings` is 3, then the a task will first be retried in
+  // 10s. The retry interval will double three times, and then
+  // increase linearly by 2^3 * 10s.  Finally, the task will retry at
+  // intervals of [max_backoff][google.cloud.tasks.v2beta3.RetryConfig.max_backoff] until the
+  // task has been attempted [max_attempts][google.cloud.tasks.v2beta3.RetryConfig.max_attempts]
+  // times. Thus, the requests will retry at 10s, 20s, 40s, 80s, 160s,
+  // 240s, 300s, 300s, ....
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  //
+  // This field has the same meaning as
+  // [max_doublings in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#retry_parameters).
+  int32 max_doublings = 5;
+}
diff --git a/tasks/google/cloud/tasks_v2beta2/proto/target.proto b/tasks/google/cloud/tasks_v2beta2/proto/target.proto
new file mode 100644
index 000000000000..087249f93d2c
--- /dev/null
+++ b/tasks/google/cloud/tasks_v2beta2/proto/target.proto
@@ -0,0 +1,282 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.tasks.v2beta3;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3;tasks";
+option java_multiple_files = true;
+option java_outer_classname = "TargetProto";
+option java_package = "com.google.cloud.tasks.v2beta3";
+
+
+// App Engine HTTP queue.
+//
+// The task will be delivered to the App Engine application hostname
+// specified by its [AppEngineHttpQueue][google.cloud.tasks.v2beta3.AppEngineHttpQueue] and [AppEngineHttpRequest][google.cloud.tasks.v2beta3.AppEngineHttpRequest].
+// The documentation for [AppEngineHttpRequest][google.cloud.tasks.v2beta3.AppEngineHttpRequest] explains how the
+// task's host URL is constructed.
+//
+// Using [AppEngineHttpQueue][google.cloud.tasks.v2beta3.AppEngineHttpQueue] requires
+// [`appengine.applications.get`](https://cloud.google.com/appengine/docs/admin-api/access-control)
+// Google IAM permission for the project
+// and the following scope:
+//
+// `https://www.googleapis.com/auth/cloud-platform`
+message AppEngineHttpQueue {
+  // Overrides for the
+  // [task-level app_engine_routing][google.cloud.tasks.v2beta3.AppEngineHttpRequest.app_engine_routing].
+  //
+  // If set, `app_engine_routing_override` is used for all tasks in
+  // the queue, no matter what the setting is for the
+  // [task-level app_engine_routing][google.cloud.tasks.v2beta3.AppEngineHttpRequest.app_engine_routing].
+  AppEngineRouting app_engine_routing_override = 1;
+}
+
+// App Engine HTTP request.
+//
+// The message defines the HTTP request that is sent to an App Engine app when
+// the task is dispatched.
+//
+// This proto can only be used for tasks in a queue which has
+// [app_engine_http_queue][google.cloud.tasks.v2beta3.Queue.app_engine_http_queue] set.
+//
+// Using [AppEngineHttpRequest][google.cloud.tasks.v2beta3.AppEngineHttpRequest] requires
+// [`appengine.applications.get`](https://cloud.google.com/appengine/docs/admin-api/access-control)
+// Google IAM permission for the project
+// and the following scope:
+//
+// `https://www.googleapis.com/auth/cloud-platform`
+//
+// The task will be delivered to the App Engine app which belongs to the same
+// project as the queue. For more information, see
+// [How Requests are Routed](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed)
+// and how routing is affected by
+// [dispatch files](https://cloud.google.com/appengine/docs/python/config/dispatchref).
+// Traffic is encrypted during transport and never leaves Google datacenters.
+// Because this traffic is carried over a communication mechanism internal to
+// Google, you cannot explicitly set the protocol (for example, HTTP or HTTPS).
+// The request to the handler, however, will appear to have used the HTTP
+// protocol.
+//
+// The [AppEngineRouting][google.cloud.tasks.v2beta3.AppEngineRouting] used to construct the URL that the task is
+// delivered to can be set at the queue-level or task-level:
+//
+// * If set,
+//    [app_engine_routing_override][google.cloud.tasks.v2beta3.AppEngineHttpQueue.app_engine_routing_override]
+//    is used for all tasks in the queue, no matter what the setting
+//    is for the
+//    [task-level app_engine_routing][google.cloud.tasks.v2beta3.AppEngineHttpRequest.app_engine_routing].
+//
+//
+// The `url` that the task will be sent to is:
+//
+// * `url =` [host][google.cloud.tasks.v2beta3.AppEngineRouting.host] `+`
+//   [relative_uri][google.cloud.tasks.v2beta3.AppEngineHttpRequest.relative_uri]
+//
+// Tasks can be dispatched to secure app handlers, unsecure app handlers, and
+// URIs restricted with
+// [`login: admin`](https://cloud.google.com/appengine/docs/standard/python/config/appref).
+// Because tasks are not run as any user, they cannot be dispatched to URIs
+// restricted with
+// [`login: required`](https://cloud.google.com/appengine/docs/standard/python/config/appref)
+// Task dispatches also do not follow redirects.
+//
+// The task attempt has succeeded if the app's request handler returns
+// an HTTP response code in the range [`200` - `299`]. `503` is
+// considered an App Engine system error instead of an application
+// error. Requests returning error `503` will be retried regardless of
+// retry configuration and not counted against retry counts.
+// Any other response code or a failure to receive a response before the
+// deadline is a failed attempt.
+message AppEngineHttpRequest {
+  // The HTTP method to use for the request. The default is POST.
+  //
+  // The app's request handler for the task's target URL must be able to handle
+  // HTTP requests with this http_method, otherwise the task attempt will fail
+  // with error code 405 (Method Not Allowed). See
+  // [Writing a push task request handler](https://cloud.google.com/appengine/docs/java/taskqueue/push/creating-handlers#writing_a_push_task_request_handler)
+  // and the documentation for the request handlers in the language your app is
+  // written in e.g.
+  // [Python Request Handler](https://cloud.google.com/appengine/docs/python/tools/webapp/requesthandlerclass).
+  HttpMethod http_method = 1;
+
+  // Task-level setting for App Engine routing.
+  //
+  // If set,
+  // [app_engine_routing_override][google.cloud.tasks.v2beta3.AppEngineHttpQueue.app_engine_routing_override]
+  // is used for all tasks in the queue, no matter what the setting is for the
+  // [task-level app_engine_routing][google.cloud.tasks.v2beta3.AppEngineHttpRequest.app_engine_routing].
+  AppEngineRouting app_engine_routing = 2;
+
+  // The relative URI.
+  //
+  // The relative URI must begin with "/" and must be a valid HTTP relative URI.
+  // It can contain a path and query string arguments.
+  // If the relative URI is empty, then the root path "/" will be used.
+  // No spaces are allowed, and the maximum length allowed is 2083 characters.
+  string relative_uri = 3;
+
+  // HTTP request headers.
+  //
+  // This map contains the header field names and values.
+  // Headers can be set when the
+  // [task is created][google.cloud.tasks.v2beta3.CloudTasks.CreateTask].
+  // Repeated headers are not supported but a header value can contain commas.
+  //
+  // Cloud Tasks sets some headers to default values:
+  //
+  // * `User-Agent`: By default, this header is
+  //   `"AppEngine-Google; (+http://code.google.com/appengine)"`.
+  //   This header can be modified, but Cloud Tasks will append
+  //   `"AppEngine-Google; (+http://code.google.com/appengine)"` to the
+  //   modified `User-Agent`.
+  //
+  // If the task has a [body][google.cloud.tasks.v2beta3.AppEngineHttpRequest.body], Cloud
+  // Tasks sets the following headers:
+  //
+  // * `Content-Type`: By default, the `Content-Type` header is set to
+  //   `"application/octet-stream"`. The default can be overridden by explicitly
+  //   setting `Content-Type` to a particular media type when the
+  //   [task is created][google.cloud.tasks.v2beta3.CloudTasks.CreateTask].
+  //   For example, `Content-Type` can be set to `"application/json"`.
+  // * `Content-Length`: This is computed by Cloud Tasks. This value is
+  //   output only.   It cannot be changed.
+  //
+  // The headers below cannot be set or overridden:
+  //
+  // * `Host`
+  // * `X-Google-*`
+  // * `X-AppEngine-*`
+  //
+  // In addition, Cloud Tasks sets some headers when the task is dispatched,
+  // such as headers containing information about the task; see
+  // [request headers](https://cloud.google.com/appengine/docs/python/taskqueue/push/creating-handlers#reading_request_headers).
+  // These headers are set only when the task is dispatched, so they are not
+  // visible when the task is returned in a Cloud Tasks response.
+  //
+  // Although there is no specific limit for the maximum number of headers or
+  // the size, there is a limit on the maximum size of the [Task][google.cloud.tasks.v2beta3.Task]. For more
+  // information, see the [CreateTask][google.cloud.tasks.v2beta3.CloudTasks.CreateTask] documentation.
+  map<string, string> headers = 4;
+
+  // HTTP request body.
+  //
+  // A request body is allowed only if the HTTP method is POST or PUT. It is
+  // an error to set a body on a task with an incompatible [HttpMethod][google.cloud.tasks.v2beta3.HttpMethod].
+  bytes body = 5;
+}
+
+// App Engine Routing.
+//
+// Defines routing characteristics specific to App Engine - service, version,
+// and instance.
+//
+// For more information about services, versions, and instances see
+// [An Overview of App Engine](https://cloud.google.com/appengine/docs/python/an-overview-of-app-engine),
+// [Microservices Architecture on Google App Engine](https://cloud.google.com/appengine/docs/python/microservices-on-app-engine),
+// [App Engine Standard request routing](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed),
+// and [App Engine Flex request routing](https://cloud.google.com/appengine/docs/flexible/python/how-requests-are-routed).
+message AppEngineRouting {
+  // App service.
+  //
+  // By default, the task is sent to the service which is the default
+  // service when the task is attempted.
+  //
+  // For some queues or tasks which were created using the App Engine
+  // Task Queue API, [host][google.cloud.tasks.v2beta3.AppEngineRouting.host] is not parsable
+  // into [service][google.cloud.tasks.v2beta3.AppEngineRouting.service],
+  // [version][google.cloud.tasks.v2beta3.AppEngineRouting.version], and
+  // [instance][google.cloud.tasks.v2beta3.AppEngineRouting.instance]. For example, some tasks
+  // which were created using the App Engine SDK use a custom domain
+  // name; custom domains are not parsed by Cloud Tasks. If
+  // [host][google.cloud.tasks.v2beta3.AppEngineRouting.host] is not parsable, then
+  // [service][google.cloud.tasks.v2beta3.AppEngineRouting.service],
+  // [version][google.cloud.tasks.v2beta3.AppEngineRouting.version], and
+  // [instance][google.cloud.tasks.v2beta3.AppEngineRouting.instance] are the empty string.
+  string service = 1;
+
+  // App version.
+  //
+  // By default, the task is sent to the version which is the default
+  // version when the task is attempted.
+  //
+  // For some queues or tasks which were created using the App Engine
+  // Task Queue API, [host][google.cloud.tasks.v2beta3.AppEngineRouting.host] is not parsable
+  // into [service][google.cloud.tasks.v2beta3.AppEngineRouting.service],
+  // [version][google.cloud.tasks.v2beta3.AppEngineRouting.version], and
+  // [instance][google.cloud.tasks.v2beta3.AppEngineRouting.instance]. For example, some tasks
+  // which were created using the App Engine SDK use a custom domain
+  // name; custom domains are not parsed by Cloud Tasks. If
+  // [host][google.cloud.tasks.v2beta3.AppEngineRouting.host] is not parsable, then
+  // [service][google.cloud.tasks.v2beta3.AppEngineRouting.service],
+  // [version][google.cloud.tasks.v2beta3.AppEngineRouting.version], and
+  // [instance][google.cloud.tasks.v2beta3.AppEngineRouting.instance] are the empty string.
+  string version = 2;
+
+  // App instance.
+  //
+  // By default, the task is sent to an instance which is available when
+  // the task is attempted.
+  //
+  // Requests can only be sent to a specific instance if
+  // [manual scaling is used in App Engine Standard](https://cloud.google.com/appengine/docs/python/an-overview-of-app-engine?hl=en_US#scaling_types_and_instance_classes).
+  // App Engine Flex does not support instances. For more information, see
+  // [App Engine Standard request routing](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed)
+  // and [App Engine Flex request routing](https://cloud.google.com/appengine/docs/flexible/python/how-requests-are-routed).
+  string instance = 3;
+
+  // Output only. The host that the task is sent to.
+  //
+  // The host is constructed from the domain name of the app associated with
+  // the queue's project ID (for example <app-id>.appspot.com), and the
+  // [service][google.cloud.tasks.v2beta3.AppEngineRouting.service], [version][google.cloud.tasks.v2beta3.AppEngineRouting.version],
+  // and [instance][google.cloud.tasks.v2beta3.AppEngineRouting.instance]. Tasks which were created using
+  // the App Engine SDK might have a custom domain name.
+  //
+  // For more information, see
+  // [How Requests are Routed](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed).
+  string host = 4;
+}
+
+// The HTTP method used to execute the task.
+enum HttpMethod {
+  // HTTP method unspecified
+  HTTP_METHOD_UNSPECIFIED = 0;
+
+  // HTTP POST
+  POST = 1;
+
+  // HTTP GET
+  GET = 2;
+
+  // HTTP HEAD
+  HEAD = 3;
+
+  // HTTP PUT
+  PUT = 4;
+
+  // HTTP DELETE
+  DELETE = 5;
+
+  // HTTP PATCH
+  PATCH = 6;
+
+  // HTTP OPTIONS
+  OPTIONS = 7;
+}
diff --git a/tasks/google/cloud/tasks_v2beta2/proto/task.proto b/tasks/google/cloud/tasks_v2beta2/proto/task.proto
new file mode 100644
index 000000000000..46026f70e62f
--- /dev/null
+++ b/tasks/google/cloud/tasks_v2beta2/proto/task.proto
@@ -0,0 +1,179 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.tasks.v2beta3;
+
+import "google/api/annotations.proto";
+import "google/cloud/tasks/v2beta3/target.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3;tasks";
+option java_multiple_files = true;
+option java_outer_classname = "TaskProto";
+option java_package = "com.google.cloud.tasks.v2beta3";
+
+
+// A unit of scheduled work.
+message Task {
+  // The view specifies a subset of [Task][google.cloud.tasks.v2beta3.Task] data.
+  //
+  // When a task is returned in a response, not all
+  // information is retrieved by default because some data, such as
+  // payloads, might be desirable to return only when needed because
+  // of its large size or because of the sensitivity of data that it
+  // contains.
+  enum View {
+    // Unspecified. Defaults to BASIC.
+    VIEW_UNSPECIFIED = 0;
+
+    // The basic view omits fields which can be large or can contain
+    // sensitive data.
+    //
+    // This view does not include the
+    // [body in AppEngineHttpRequest][google.cloud.tasks.v2beta3.AppEngineHttpRequest.body].
+    // Bodies are desirable to return only when needed, because they
+    // can be large and because of the sensitivity of the data that you
+    // choose to store in it.
+    BASIC = 1;
+
+    // All information is returned.
+    //
+    // Authorization for [FULL][google.cloud.tasks.v2beta3.Task.View.FULL] requires
+    // `cloudtasks.tasks.fullView` [Google IAM](https://cloud.google.com/iam/)
+    // permission on the [Queue][google.cloud.tasks.v2beta3.Queue] resource.
+    FULL = 2;
+  }
+
+  // Optionally caller-specified in [CreateTask][google.cloud.tasks.v2beta3.CloudTasks.CreateTask].
+  //
+  // The task name.
+  //
+  // The task name must have the following format:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID`
+  //
+  // * `PROJECT_ID` can contain letters ([A-Za-z]), numbers ([0-9]),
+  //    hyphens (-), colons (:), or periods (.).
+  //    For more information, see
+  //    [Identifying projects](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects)
+  // * `LOCATION_ID` is the canonical ID for the task's location.
+  //    The list of available locations can be obtained by calling
+  //    [ListLocations][google.cloud.location.Locations.ListLocations].
+  //    For more information, see https://cloud.google.com/about/locations/.
+  // * `QUEUE_ID` can contain letters ([A-Za-z]), numbers ([0-9]), or
+  //   hyphens (-). The maximum length is 100 characters.
+  // * `TASK_ID` can contain only letters ([A-Za-z]), numbers ([0-9]),
+  //   hyphens (-), or underscores (_). The maximum length is 500 characters.
+  string name = 1;
+
+  // Required. The message to send to the worker.
+  oneof payload_type {
+    // HTTP request that is sent to the App Engine app handler.
+    //
+    // An App Engine task is a task that has [AppEngineHttpRequest][google.cloud.tasks.v2beta3.AppEngineHttpRequest] set.
+    AppEngineHttpRequest app_engine_http_request = 3;
+  }
+
+  // The time when the task is scheduled to be attempted.
+  //
+  // For App Engine queues, this is when the task will be attempted or retried.
+  //
+  // `schedule_time` will be truncated to the nearest microsecond.
+  google.protobuf.Timestamp schedule_time = 4;
+
+  // Output only. The time that the task was created.
+  //
+  // `create_time` will be truncated to the nearest second.
+  google.protobuf.Timestamp create_time = 5;
+
+  // The deadline for requests sent to the worker. If the worker does not
+  // respond by this deadline then the request is cancelled and the attempt
+  // is marked as a `DEADLINE_EXCEEDED` failure. Cloud Tasks will retry the
+  // task according to the [RetryConfig][google.cloud.tasks.v2beta3.RetryConfig].
+  //
+  // Note that when the request is cancelled, Cloud Tasks will stop listing for
+  // the response, but whether the worker stops processing depends on the
+  // worker. For example, if the worker is stuck, it may not react to cancelled
+  // requests.
+  //
+  // The default and maximum values depend on the type of request:
+  //
+  //
+  // * For [App Engine tasks][google.cloud.tasks.v2beta3.AppEngineHttpRequest], 0 indicates that the
+  //   request has the default deadline. The default deadline depends on the
+  //   [scaling type](https://cloud.google.com/appengine/docs/standard/go/how-instances-are-managed#instance_scaling)
+  //   of the service: 10 minutes for standard apps with automatic scaling, 24
+  //   hours for standard apps with manual and basic scaling, and 60 minutes for
+  //   flex apps. If the request deadline is set, it must be in the interval [15
+  //   seconds, 24 hours 15 seconds]. Regardless of the task's
+  //   `dispatch_deadline`, the app handler will not run for longer than than
+  //   the service's timeout. We recommend setting the `dispatch_deadline` to
+  //   at most a few seconds more than the app handler's timeout. For more
+  //   information see
+  //   [Timeouts](https://cloud.google.com/tasks/docs/creating-appengine-handlers#timeouts).
+  //
+  // `dispatch_deadline` will be truncated to the nearest millisecond. The
+  // deadline is an approximate deadline.
+  google.protobuf.Duration dispatch_deadline = 12;
+
+  // Output only. The number of attempts dispatched.
+  //
+  // This count includes tasks which have been dispatched but haven't
+  // received a response.
+  int32 dispatch_count = 6;
+
+  // Output only. The number of attempts which have received a response.
+  int32 response_count = 7;
+
+  // Output only. The status of the task's first attempt.
+  //
+  // Only [dispatch_time][google.cloud.tasks.v2beta3.Attempt.dispatch_time] will be set.
+  // The other [Attempt][google.cloud.tasks.v2beta3.Attempt] information is not retained by Cloud Tasks.
+  Attempt first_attempt = 8;
+
+  // Output only. The status of the task's last attempt.
+  Attempt last_attempt = 9;
+
+  // Output only. The view specifies which subset of the [Task][google.cloud.tasks.v2beta3.Task] has
+  // been returned.
+  View view = 10;
+}
+
+// The status of a task attempt.
+message Attempt {
+  // Output only. The time that this attempt was scheduled.
+  //
+  // `schedule_time` will be truncated to the nearest microsecond.
+  google.protobuf.Timestamp schedule_time = 1;
+
+  // Output only. The time that this attempt was dispatched.
+  //
+  // `dispatch_time` will be truncated to the nearest microsecond.
+  google.protobuf.Timestamp dispatch_time = 2;
+
+  // Output only. The time that this attempt response was received.
+  //
+  // `response_time` will be truncated to the nearest microsecond.
+  google.protobuf.Timestamp response_time = 3;
+
+  // Output only. The response from the worker for this attempt.
+  //
+  // If `response_time` is unset, then the task has not been attempted or is
+  // currently running and the `response_status` field is meaningless.
+  google.rpc.Status response_status = 4;
+}
diff --git a/tasks/google/cloud/tasks_v2beta3/proto/cloudtasks.proto b/tasks/google/cloud/tasks_v2beta3/proto/cloudtasks.proto
new file mode 100644
index 000000000000..fcdd9cf9e558
--- /dev/null
+++ b/tasks/google/cloud/tasks_v2beta3/proto/cloudtasks.proto
@@ -0,0 +1,600 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.tasks.v2beta3;
+
+import "google/api/annotations.proto";
+import "google/cloud/tasks/v2beta3/queue.proto";
+import "google/cloud/tasks/v2beta3/task.proto";
+import "google/iam/v1/iam_policy.proto";
+import "google/iam/v1/policy.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/rpc/code.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3;tasks";
+option java_multiple_files = true;
+option java_outer_classname = "CloudTasksProto";
+option java_package = "com.google.cloud.tasks.v2beta3";
+option objc_class_prefix = "TASKS";
+
+
+// Cloud Tasks allows developers to manage the execution of background
+// work in their applications.
+service CloudTasks {
+  // Lists queues.
+  //
+  // Queues are returned in lexicographical order.
+  rpc ListQueues(ListQueuesRequest) returns (ListQueuesResponse) {
+    option (google.api.http) = {
+      get: "/v2beta3/{parent=projects/*/locations/*}/queues"
+    };
+  }
+
+  // Gets a queue.
+  rpc GetQueue(GetQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      get: "/v2beta3/{name=projects/*/locations/*/queues/*}"
+    };
+  }
+
+  // Creates a queue.
+  //
+  // Queues created with this method allow tasks to live for a maximum of 31
+  // days. After a task is 31 days old, the task will be deleted regardless of whether
+  // it was dispatched or not.
+  //
+  // WARNING: Using this method may have unintended side effects if you are
+  // using an App Engine `queue.yaml` or `queue.xml` file to manage your queues.
+  // Read
+  // [Overview of Queue Management and queue.yaml](https://cloud.google.com/tasks/docs/queue-yaml)
+  // before using this method.
+  rpc CreateQueue(CreateQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      post: "/v2beta3/{parent=projects/*/locations/*}/queues"
+      body: "queue"
+    };
+  }
+
+  // Updates a queue.
+  //
+  // This method creates the queue if it does not exist and updates
+  // the queue if it does exist.
+  //
+  // Queues created with this method allow tasks to live for a maximum of 31
+  // days. After a task is 31 days old, the task will be deleted regardless of whether
+  // it was dispatched or not.
+  //
+  // WARNING: Using this method may have unintended side effects if you are
+  // using an App Engine `queue.yaml` or `queue.xml` file to manage your queues.
+  // Read
+  // [Overview of Queue Management and queue.yaml](https://cloud.google.com/tasks/docs/queue-yaml)
+  // before using this method.
+  rpc UpdateQueue(UpdateQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      patch: "/v2beta3/{queue.name=projects/*/locations/*/queues/*}"
+      body: "queue"
+    };
+  }
+
+  // Deletes a queue.
+  //
+  // This command will delete the queue even if it has tasks in it.
+  //
+  // Note: If you delete a queue, a queue with the same name can't be created
+  // for 7 days.
+  //
+  // WARNING: Using this method may have unintended side effects if you are
+  // using an App Engine `queue.yaml` or `queue.xml` file to manage your queues.
+  // Read
+  // [Overview of Queue Management and queue.yaml](https://cloud.google.com/tasks/docs/queue-yaml)
+  // before using this method.
+  rpc DeleteQueue(DeleteQueueRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2beta3/{name=projects/*/locations/*/queues/*}"
+    };
+  }
+
+  // Purges a queue by deleting all of its tasks.
+  //
+  // All tasks created before this method is called are permanently deleted.
+  //
+  // Purge operations can take up to one minute to take effect. Tasks
+  // might be dispatched before the purge takes effect. A purge is irreversible.
+  rpc PurgeQueue(PurgeQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      post: "/v2beta3/{name=projects/*/locations/*/queues/*}:purge"
+      body: "*"
+    };
+  }
+
+  // Pauses the queue.
+  //
+  // If a queue is paused then the system will stop dispatching tasks
+  // until the queue is resumed via
+  // [ResumeQueue][google.cloud.tasks.v2beta3.CloudTasks.ResumeQueue]. Tasks can still be added
+  // when the queue is paused. A queue is paused if its
+  // [state][google.cloud.tasks.v2beta3.Queue.state] is [PAUSED][google.cloud.tasks.v2beta3.Queue.State.PAUSED].
+  rpc PauseQueue(PauseQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      post: "/v2beta3/{name=projects/*/locations/*/queues/*}:pause"
+      body: "*"
+    };
+  }
+
+  // Resume a queue.
+  //
+  // This method resumes a queue after it has been
+  // [PAUSED][google.cloud.tasks.v2beta3.Queue.State.PAUSED] or
+  // [DISABLED][google.cloud.tasks.v2beta3.Queue.State.DISABLED]. The state of a queue is stored
+  // in the queue's [state][google.cloud.tasks.v2beta3.Queue.state]; after calling this method it
+  // will be set to [RUNNING][google.cloud.tasks.v2beta3.Queue.State.RUNNING].
+  //
+  // WARNING: Resuming many high-QPS queues at the same time can
+  // lead to target overloading. If you are resuming high-QPS
+  // queues, follow the 500/50/5 pattern described in
+  // [Managing Cloud Tasks Scaling Risks](https://cloud.google.com/tasks/docs/manage-cloud-task-scaling).
+  rpc ResumeQueue(ResumeQueueRequest) returns (Queue) {
+    option (google.api.http) = {
+      post: "/v2beta3/{name=projects/*/locations/*/queues/*}:resume"
+      body: "*"
+    };
+  }
+
+  // Gets the access control policy for a [Queue][google.cloud.tasks.v2beta3.Queue].
+  // Returns an empty policy if the resource exists and does not have a policy
+  // set.
+  //
+  // Authorization requires the following
+  // [Google IAM](https://cloud.google.com/iam) permission on the specified
+  // resource parent:
+  //
+  // * `cloudtasks.queues.getIamPolicy`
+  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v2beta3/{resource=projects/*/locations/*/queues/*}:getIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Sets the access control policy for a [Queue][google.cloud.tasks.v2beta3.Queue]. Replaces any existing
+  // policy.
+  //
+  // Note: The Cloud Console does not check queue-level IAM permissions yet.
+  // Project-level permissions are required to use the Cloud Console.
+  //
+  // Authorization requires the following
+  // [Google IAM](https://cloud.google.com/iam) permission on the specified
+  // resource parent:
+  //
+  // * `cloudtasks.queues.setIamPolicy`
+  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) {
+    option (google.api.http) = {
+      post: "/v2beta3/{resource=projects/*/locations/*/queues/*}:setIamPolicy"
+      body: "*"
+    };
+  }
+
+  // Returns permissions that a caller has on a [Queue][google.cloud.tasks.v2beta3.Queue].
+  // If the resource does not exist, this will return an empty set of
+  // permissions, not a [NOT_FOUND][google.rpc.Code.NOT_FOUND] error.
+  //
+  // Note: This operation is designed to be used for building permission-aware
+  // UIs and command-line tools, not for authorization checking. This operation
+  // may "fail open" without warning.
+  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) {
+    option (google.api.http) = {
+      post: "/v2beta3/{resource=projects/*/locations/*/queues/*}:testIamPermissions"
+      body: "*"
+    };
+  }
+
+  // Lists the tasks in a queue.
+  //
+  // By default, only the [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC] view is retrieved
+  // due to performance considerations;
+  // [response_view][google.cloud.tasks.v2beta3.ListTasksRequest.response_view] controls the
+  // subset of information which is returned.
+  //
+  // The tasks may be returned in any order. The ordering may change at any
+  // time.
+  rpc ListTasks(ListTasksRequest) returns (ListTasksResponse) {
+    option (google.api.http) = {
+      get: "/v2beta3/{parent=projects/*/locations/*/queues/*}/tasks"
+    };
+  }
+
+  // Gets a task.
+  rpc GetTask(GetTaskRequest) returns (Task) {
+    option (google.api.http) = {
+      get: "/v2beta3/{name=projects/*/locations/*/queues/*/tasks/*}"
+    };
+  }
+
+  // Creates a task and adds it to a queue.
+  //
+  // Tasks cannot be updated after creation; there is no UpdateTask command.
+  //
+  // * For [App Engine queues][google.cloud.tasks.v2beta3.AppEngineHttpQueue], the maximum task size is
+  //   100KB.
+  rpc CreateTask(CreateTaskRequest) returns (Task) {
+    option (google.api.http) = {
+      post: "/v2beta3/{parent=projects/*/locations/*/queues/*}/tasks"
+      body: "*"
+    };
+  }
+
+  // Deletes a task.
+  //
+  // A task can be deleted if it is scheduled or dispatched. A task
+  // cannot be deleted if it has executed successfully or permanently
+  // failed.
+  rpc DeleteTask(DeleteTaskRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v2beta3/{name=projects/*/locations/*/queues/*/tasks/*}"
+    };
+  }
+
+  // Forces a task to run now.
+  //
+  // When this method is called, Cloud Tasks will dispatch the task, even if
+  // the task is already running, the queue has reached its [RateLimits][google.cloud.tasks.v2beta3.RateLimits] or
+  // is [PAUSED][google.cloud.tasks.v2beta3.Queue.State.PAUSED].
+  //
+  // This command is meant to be used for manual debugging. For
+  // example, [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask] can be used to retry a failed
+  // task after a fix has been made or to manually force a task to be
+  // dispatched now.
+  //
+  // The dispatched task is returned. That is, the task that is returned
+  // contains the [status][Task.status] after the task is dispatched but
+  // before the task is received by its target.
+  //
+  // If Cloud Tasks receives a successful response from the task's
+  // target, then the task will be deleted; otherwise the task's
+  // [schedule_time][google.cloud.tasks.v2beta3.Task.schedule_time] will be reset to the time that
+  // [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask] was called plus the retry delay specified
+  // in the queue's [RetryConfig][google.cloud.tasks.v2beta3.RetryConfig].
+  //
+  // [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask] returns
+  // [NOT_FOUND][google.rpc.Code.NOT_FOUND] when it is called on a
+  // task that has already succeeded or permanently failed.
+  rpc RunTask(RunTaskRequest) returns (Task) {
+    option (google.api.http) = {
+      post: "/v2beta3/{name=projects/*/locations/*/queues/*/tasks/*}:run"
+      body: "*"
+    };
+  }
+}
+
+// Request message for [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues].
+message ListQueuesRequest {
+  // Required.
+  //
+  // The location name.
+  // For example: `projects/PROJECT_ID/locations/LOCATION_ID`
+  string parent = 1;
+
+  // `filter` can be used to specify a subset of queues. Any [Queue][google.cloud.tasks.v2beta3.Queue]
+  // field can be used as a filter and several operators as supported.
+  // For example: `<=, <, >=, >, !=, =, :`. The filter syntax is the same as
+  // described in
+  // [Stackdriver's Advanced Logs Filters](https://cloud.google.com/logging/docs/view/advanced_filters).
+  //
+  // Sample filter "state: PAUSED".
+  //
+  // Note that using filters might cause fewer queues than the
+  // requested page_size to be returned.
+  string filter = 2;
+
+  // Requested page size.
+  //
+  // The maximum page size is 9800. If unspecified, the page size will
+  // be the maximum. Fewer queues than requested might be returned,
+  // even if more queues exist; use the
+  // [next_page_token][google.cloud.tasks.v2beta3.ListQueuesResponse.next_page_token] in the
+  // response to determine if more queues exist.
+  int32 page_size = 3;
+
+  // A token identifying the page of results to return.
+  //
+  // To request the first page results, page_token must be empty. To
+  // request the next page of results, page_token must be the value of
+  // [next_page_token][google.cloud.tasks.v2beta3.ListQueuesResponse.next_page_token] returned
+  // from the previous call to [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues]
+  // method. It is an error to switch the value of the
+  // [filter][google.cloud.tasks.v2beta3.ListQueuesRequest.filter] while iterating through pages.
+  string page_token = 4;
+}
+
+// Response message for [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues].
+message ListQueuesResponse {
+  // The list of queues.
+  repeated Queue queues = 1;
+
+  // A token to retrieve next page of results.
+  //
+  // To return the next page of results, call
+  // [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues] with this value as the
+  // [page_token][google.cloud.tasks.v2beta3.ListQueuesRequest.page_token].
+  //
+  // If the next_page_token is empty, there are no more results.
+  //
+  // The page token is valid for only 2 hours.
+  string next_page_token = 2;
+}
+
+// Request message for [GetQueue][google.cloud.tasks.v2beta3.CloudTasks.GetQueue].
+message GetQueueRequest {
+  // Required.
+  //
+  // The resource name of the queue. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID`
+  string name = 1;
+}
+
+// Request message for [CreateQueue][google.cloud.tasks.v2beta3.CloudTasks.CreateQueue].
+message CreateQueueRequest {
+  // Required.
+  //
+  // The location name in which the queue will be created.
+  // For example: `projects/PROJECT_ID/locations/LOCATION_ID`
+  //
+  // The list of allowed locations can be obtained by calling Cloud
+  // Tasks' implementation of
+  // [ListLocations][google.cloud.location.Locations.ListLocations].
+  string parent = 1;
+
+  // Required.
+  //
+  // The queue to create.
+  //
+  // [Queue's name][google.cloud.tasks.v2beta3.Queue.name] cannot be the same as an existing queue.
+  Queue queue = 2;
+}
+
+// Request message for [UpdateQueue][google.cloud.tasks.v2beta3.CloudTasks.UpdateQueue].
+message UpdateQueueRequest {
+  // Required.
+  //
+  // The queue to create or update.
+  //
+  // The queue's [name][google.cloud.tasks.v2beta3.Queue.name] must be specified.
+  //
+  // Output only fields cannot be modified using UpdateQueue.
+  // Any value specified for an output only field will be ignored.
+  // The queue's [name][google.cloud.tasks.v2beta3.Queue.name] cannot be changed.
+  Queue queue = 1;
+
+  // A mask used to specify which fields of the queue are being updated.
+  //
+  // If empty, then all fields will be updated.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for [DeleteQueue][google.cloud.tasks.v2beta3.CloudTasks.DeleteQueue].
+message DeleteQueueRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID`
+  string name = 1;
+}
+
+// Request message for [PurgeQueue][google.cloud.tasks.v2beta3.CloudTasks.PurgeQueue].
+message PurgeQueueRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/location/LOCATION_ID/queues/QUEUE_ID`
+  string name = 1;
+}
+
+// Request message for [PauseQueue][google.cloud.tasks.v2beta3.CloudTasks.PauseQueue].
+message PauseQueueRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/location/LOCATION_ID/queues/QUEUE_ID`
+  string name = 1;
+}
+
+// Request message for [ResumeQueue][google.cloud.tasks.v2beta3.CloudTasks.ResumeQueue].
+message ResumeQueueRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/location/LOCATION_ID/queues/QUEUE_ID`
+  string name = 1;
+}
+
+// Request message for listing tasks using [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks].
+message ListTasksRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID`
+  string parent = 1;
+
+  // The response_view specifies which subset of the [Task][google.cloud.tasks.v2beta3.Task] will be
+  // returned.
+  //
+  // By default response_view is [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC]; not all
+  // information is retrieved by default because some data, such as
+  // payloads, might be desirable to return only when needed because
+  // of its large size or because of the sensitivity of data that it
+  // contains.
+  //
+  // Authorization for [FULL][google.cloud.tasks.v2beta3.Task.View.FULL] requires
+  // `cloudtasks.tasks.fullView` [Google IAM](https://cloud.google.com/iam/)
+  // permission on the [Task][google.cloud.tasks.v2beta3.Task] resource.
+  Task.View response_view = 2;
+
+  // Requested page size. Fewer tasks than requested might be returned.
+  //
+  // The maximum page size is 1000. If unspecified, the page size will
+  // be the maximum. Fewer tasks than requested might be returned,
+  // even if more tasks exist; use
+  // [next_page_token][google.cloud.tasks.v2beta3.ListTasksResponse.next_page_token] in the
+  // response to determine if more tasks exist.
+  int32 page_size = 3;
+
+  // A token identifying the page of results to return.
+  //
+  // To request the first page results, page_token must be empty. To
+  // request the next page of results, page_token must be the value of
+  // [next_page_token][google.cloud.tasks.v2beta3.ListTasksResponse.next_page_token] returned
+  // from the previous call to [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks]
+  // method.
+  //
+  // The page token is valid for only 2 hours.
+  string page_token = 4;
+}
+
+// Response message for listing tasks using [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks].
+message ListTasksResponse {
+  // The list of tasks.
+  repeated Task tasks = 1;
+
+  // A token to retrieve next page of results.
+  //
+  // To return the next page of results, call
+  // [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks] with this value as the
+  // [page_token][google.cloud.tasks.v2beta3.ListTasksRequest.page_token].
+  //
+  // If the next_page_token is empty, there are no more results.
+  string next_page_token = 2;
+}
+
+// Request message for getting a task using [GetTask][google.cloud.tasks.v2beta3.CloudTasks.GetTask].
+message GetTaskRequest {
+  // Required.
+  //
+  // The task name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID`
+  string name = 1;
+
+  // The response_view specifies which subset of the [Task][google.cloud.tasks.v2beta3.Task] will be
+  // returned.
+  //
+  // By default response_view is [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC]; not all
+  // information is retrieved by default because some data, such as
+  // payloads, might be desirable to return only when needed because
+  // of its large size or because of the sensitivity of data that it
+  // contains.
+  //
+  // Authorization for [FULL][google.cloud.tasks.v2beta3.Task.View.FULL] requires
+  // `cloudtasks.tasks.fullView` [Google IAM](https://cloud.google.com/iam/)
+  // permission on the [Task][google.cloud.tasks.v2beta3.Task] resource.
+  Task.View response_view = 2;
+}
+
+// Request message for [CreateTask][google.cloud.tasks.v2beta3.CloudTasks.CreateTask].
+message CreateTaskRequest {
+  // Required.
+  //
+  // The queue name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID`
+  //
+  // The queue must already exist.
+  string parent = 1;
+
+  // Required.
+  //
+  // The task to add.
+  //
+  // Task names have the following format:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID`.
+  // The user can optionally specify a task [name][google.cloud.tasks.v2beta3.Task.name]. If a
+  // name is not specified then the system will generate a random
+  // unique task id, which will be set in the task returned in the
+  // [response][google.cloud.tasks.v2beta3.Task.name].
+  //
+  // If [schedule_time][google.cloud.tasks.v2beta3.Task.schedule_time] is not set or is in the
+  // past then Cloud Tasks will set it to the current time.
+  //
+  // Task De-duplication:
+  //
+  // Explicitly specifying a task ID enables task de-duplication.  If
+  // a task's ID is identical to that of an existing task or a task
+  // that was deleted or executed recently then the call will fail
+  // with [ALREADY_EXISTS][google.rpc.Code.ALREADY_EXISTS].
+  // If the task's queue was created using Cloud Tasks, then another task with
+  // the same name can't be created for ~1hour after the original task was
+  // deleted or executed. If the task's queue was created using queue.yaml or
+  // queue.xml, then another task with the same name can't be created
+  // for ~9days after the original task was deleted or executed.
+  //
+  // Because there is an extra lookup cost to identify duplicate task
+  // names, these [CreateTask][google.cloud.tasks.v2beta3.CloudTasks.CreateTask] calls have significantly
+  // increased latency. Using hashed strings for the task id or for
+  // the prefix of the task id is recommended. Choosing task ids that
+  // are sequential or have sequential prefixes, for example using a
+  // timestamp, causes an increase in latency and error rates in all
+  // task commands. The infrastructure relies on an approximately
+  // uniform distribution of task ids to store and serve tasks
+  // efficiently.
+  Task task = 2;
+
+  // The response_view specifies which subset of the [Task][google.cloud.tasks.v2beta3.Task] will be
+  // returned.
+  //
+  // By default response_view is [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC]; not all
+  // information is retrieved by default because some data, such as
+  // payloads, might be desirable to return only when needed because
+  // of its large size or because of the sensitivity of data that it
+  // contains.
+  //
+  // Authorization for [FULL][google.cloud.tasks.v2beta3.Task.View.FULL] requires
+  // `cloudtasks.tasks.fullView` [Google IAM](https://cloud.google.com/iam/)
+  // permission on the [Task][google.cloud.tasks.v2beta3.Task] resource.
+  Task.View response_view = 3;
+}
+
+// Request message for deleting a task using
+// [DeleteTask][google.cloud.tasks.v2beta3.CloudTasks.DeleteTask].
+message DeleteTaskRequest {
+  // Required.
+  //
+  // The task name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID`
+  string name = 1;
+}
+
+// Request message for forcing a task to run now using
+// [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask].
+message RunTaskRequest {
+  // Required.
+  //
+  // The task name. For example:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID`
+  string name = 1;
+
+  // The response_view specifies which subset of the [Task][google.cloud.tasks.v2beta3.Task] will be
+  // returned.
+  //
+  // By default response_view is [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC]; not all
+  // information is retrieved by default because some data, such as
+  // payloads, might be desirable to return only when needed because
+  // of its large size or because of the sensitivity of data that it
+  // contains.
+  //
+  // Authorization for [FULL][google.cloud.tasks.v2beta3.Task.View.FULL] requires
+  // `cloudtasks.tasks.fullView` [Google IAM](https://cloud.google.com/iam/)
+  // permission on the [Task][google.cloud.tasks.v2beta3.Task] resource.
+  Task.View response_view = 2;
+}
diff --git a/tasks/google/cloud/tasks_v2beta3/proto/queue.proto b/tasks/google/cloud/tasks_v2beta3/proto/queue.proto
new file mode 100644
index 000000000000..4b6b92663651
--- /dev/null
+++ b/tasks/google/cloud/tasks_v2beta3/proto/queue.proto
@@ -0,0 +1,326 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.tasks.v2beta3;
+
+import "google/api/annotations.proto";
+import "google/cloud/tasks/v2beta3/target.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3;tasks";
+option java_multiple_files = true;
+option java_outer_classname = "QueueProto";
+option java_package = "com.google.cloud.tasks.v2beta3";
+
+
+// A queue is a container of related tasks. Queues are configured to manage
+// how those tasks are dispatched. Configurable properties include rate limits,
+// retry options, queue types, and others.
+message Queue {
+  // State of the queue.
+  enum State {
+    // Unspecified state.
+    STATE_UNSPECIFIED = 0;
+
+    // The queue is running. Tasks can be dispatched.
+    //
+    // If the queue was created using Cloud Tasks and the queue has
+    // had no activity (method calls or task dispatches) for 30 days,
+    // the queue may take a few minutes to re-activate. Some method
+    // calls may return [NOT_FOUND][google.rpc.Code.NOT_FOUND] and
+    // tasks may not be dispatched for a few minutes until the queue
+    // has been re-activated.
+    RUNNING = 1;
+
+    // Tasks are paused by the user. If the queue is paused then Cloud
+    // Tasks will stop delivering tasks from it, but more tasks can
+    // still be added to it by the user.
+    PAUSED = 2;
+
+    // The queue is disabled.
+    //
+    // A queue becomes `DISABLED` when
+    // [queue.yaml](https://cloud.google.com/appengine/docs/python/config/queueref)
+    // or
+    // [queue.xml](https://cloud.google.com/appengine/docs/standard/java/config/queueref)
+    // is uploaded which does not contain the queue. You cannot directly disable
+    // a queue.
+    //
+    // When a queue is disabled, tasks can still be added to a queue
+    // but the tasks are not dispatched.
+    //
+    // To permanently delete this queue and all of its tasks, call
+    // [DeleteQueue][google.cloud.tasks.v2beta3.CloudTasks.DeleteQueue].
+    DISABLED = 3;
+  }
+
+  // Caller-specified and required in [CreateQueue][google.cloud.tasks.v2beta3.CloudTasks.CreateQueue],
+  // after which it becomes output only.
+  //
+  // The queue name.
+  //
+  // The queue name must have the following format:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID`
+  //
+  // * `PROJECT_ID` can contain letters ([A-Za-z]), numbers ([0-9]),
+  //    hyphens (-), colons (:), or periods (.).
+  //    For more information, see
+  //    [Identifying projects](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects)
+  // * `LOCATION_ID` is the canonical ID for the queue's location.
+  //    The list of available locations can be obtained by calling
+  //    [ListLocations][google.cloud.location.Locations.ListLocations].
+  //    For more information, see https://cloud.google.com/about/locations/.
+  // * `QUEUE_ID` can contain letters ([A-Za-z]), numbers ([0-9]), or
+  //   hyphens (-). The maximum length is 100 characters.
+  string name = 1;
+
+  oneof queue_type {
+    // [AppEngineHttpQueue][google.cloud.tasks.v2beta3.AppEngineHttpQueue] settings apply only to
+    // [App Engine tasks][google.cloud.tasks.v2beta3.AppEngineHttpRequest] in this queue.
+    AppEngineHttpQueue app_engine_http_queue = 3;
+  }
+
+  // Rate limits for task dispatches.
+  //
+  // [rate_limits][google.cloud.tasks.v2beta3.Queue.rate_limits] and [retry_config][google.cloud.tasks.v2beta3.Queue.retry_config] are
+  // related because they both control task attempts. However they control task
+  // attempts in different ways:
+  //
+  // * [rate_limits][google.cloud.tasks.v2beta3.Queue.rate_limits] controls the total rate of
+  //   dispatches from a queue (i.e. all traffic dispatched from the
+  //   queue, regardless of whether the dispatch is from a first
+  //   attempt or a retry).
+  // * [retry_config][google.cloud.tasks.v2beta3.Queue.retry_config] controls what happens to
+  //   particular a task after its first attempt fails. That is,
+  //   [retry_config][google.cloud.tasks.v2beta3.Queue.retry_config] controls task retries (the
+  //   second attempt, third attempt, etc).
+  //
+  // The queue's actual dispatch rate is the result of:
+  //
+  // * Number of tasks in the queue
+  // * User-specified throttling: [rate limits][Queue.RateLimits]
+  //   [retry configuration][Queue.RetryConfig], and the
+  //   [queue's state][google.cloud.tasks.v2beta3.Queue.state].
+  // * System throttling due to `429` (Too Many Requests) or `503` (Service
+  //   Unavailable) responses from the worker, high error rates, or to smooth
+  //   sudden large traffic spikes.
+  RateLimits rate_limits = 4;
+
+  // Settings that determine the retry behavior.
+  //
+  // * For tasks created using Cloud Tasks: the queue-level retry settings
+  //   apply to all tasks in the queue that were created using Cloud Tasks.
+  //   Retry settings cannot be set on individual tasks.
+  // * For tasks created using the App Engine SDK: the queue-level retry
+  //   settings apply to all tasks in the queue which do not have retry settings
+  //   explicitly set on the task and were created by the App Engine SDK. See
+  //   [App Engine documentation](https://cloud.google.com/appengine/docs/standard/python/taskqueue/push/retrying-tasks).
+  RetryConfig retry_config = 5;
+
+  // Output only. The state of the queue.
+  //
+  // `state` can only be changed by called
+  // [PauseQueue][google.cloud.tasks.v2beta3.CloudTasks.PauseQueue],
+  // [ResumeQueue][google.cloud.tasks.v2beta3.CloudTasks.ResumeQueue], or uploading
+  // [queue.yaml/xml](https://cloud.google.com/appengine/docs/python/config/queueref).
+  // [UpdateQueue][google.cloud.tasks.v2beta3.CloudTasks.UpdateQueue] cannot be used to change `state`.
+  State state = 6;
+
+  // Output only. The last time this queue was purged.
+  //
+  // All tasks that were [created][google.cloud.tasks.v2beta3.Task.create_time] before this time
+  // were purged.
+  //
+  // A queue can be purged using [PurgeQueue][google.cloud.tasks.v2beta3.CloudTasks.PurgeQueue], the
+  // [App Engine Task Queue SDK, or the Cloud Console](https://cloud.google.com/appengine/docs/standard/python/taskqueue/push/deleting-tasks-and-queues#purging_all_tasks_from_a_queue).
+  //
+  // Purge time will be truncated to the nearest microsecond. Purge
+  // time will be unset if the queue has never been purged.
+  google.protobuf.Timestamp purge_time = 7;
+}
+
+// Rate limits.
+//
+// This message determines the maximum rate that tasks can be dispatched by a
+// queue, regardless of whether the dispatch is a first task attempt or a retry.
+//
+// Note: The debugging command, [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask], will run a task
+// even if the queue has reached its [RateLimits][google.cloud.tasks.v2beta3.RateLimits].
+message RateLimits {
+  // The maximum rate at which tasks are dispatched from this queue.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  // * For [App Engine queues][google.cloud.tasks.v2beta3.AppEngineHttpQueue], the maximum allowed value
+  //   is 500.
+  //
+  //
+  // This field has the same meaning as
+  // [rate in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#rate).
+  double max_dispatches_per_second = 1;
+
+  // Output only. The max burst size.
+  //
+  // Max burst size limits how fast tasks in queue are processed when
+  // many tasks are in the queue and the rate is high. This field
+  // allows the queue to have a high rate so processing starts shortly
+  // after a task is enqueued, but still limits resource usage when
+  // many tasks are enqueued in a short period of time.
+  //
+  // The [token bucket](https://wikipedia.org/wiki/Token_Bucket)
+  // algorithm is used to control the rate of task dispatches. Each
+  // queue has a token bucket that holds tokens, up to the maximum
+  // specified by `max_burst_size`. Each time a task is dispatched, a
+  // token is removed from the bucket. Tasks will be dispatched until
+  // the queue's bucket runs out of tokens. The bucket will be
+  // continuously refilled with new tokens based on
+  // [max_dispatches_per_second][google.cloud.tasks.v2beta3.RateLimits.max_dispatches_per_second].
+  //
+  // Cloud Tasks will pick the value of `max_burst_size` based on the
+  // value of
+  // [max_dispatches_per_second][google.cloud.tasks.v2beta3.RateLimits.max_dispatches_per_second].
+  //
+  // For App Engine queues that were created or updated using
+  // `queue.yaml/xml`, `max_burst_size` is equal to
+  // [bucket_size](https://cloud.google.com/appengine/docs/standard/python/config/queueref#bucket_size).
+  // Since `max_burst_size` is output only, if
+  // [UpdateQueue][google.cloud.tasks.v2beta3.CloudTasks.UpdateQueue] is called on a queue
+  // created by `queue.yaml/xml`, `max_burst_size` will be reset based
+  // on the value of
+  // [max_dispatches_per_second][google.cloud.tasks.v2beta3.RateLimits.max_dispatches_per_second],
+  // regardless of whether
+  // [max_dispatches_per_second][google.cloud.tasks.v2beta3.RateLimits.max_dispatches_per_second]
+  // is updated.
+  //
+  int32 max_burst_size = 2;
+
+  // The maximum number of concurrent tasks that Cloud Tasks allows
+  // to be dispatched for this queue. After this threshold has been
+  // reached, Cloud Tasks stops dispatching tasks until the number of
+  // concurrent requests decreases.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  //
+  // The maximum allowed value is 5,000.
+  //
+  //
+  // This field has the same meaning as
+  // [max_concurrent_requests in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#max_concurrent_requests).
+  int32 max_concurrent_dispatches = 3;
+}
+
+// Retry config.
+//
+// These settings determine when a failed task attempt is retried.
+message RetryConfig {
+  // Number of attempts per task.
+  //
+  // Cloud Tasks will attempt the task `max_attempts` times (that is, if the
+  // first attempt fails, then there will be `max_attempts - 1` retries). Must
+  // be >= -1.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  // -1 indicates unlimited attempts.
+  //
+  // This field has the same meaning as
+  // [task_retry_limit in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#retry_parameters).
+  int32 max_attempts = 1;
+
+  // If positive, `max_retry_duration` specifies the time limit for
+  // retrying a failed task, measured from when the task was first
+  // attempted. Once `max_retry_duration` time has passed *and* the
+  // task has been attempted [max_attempts][google.cloud.tasks.v2beta3.RetryConfig.max_attempts]
+  // times, no further attempts will be made and the task will be
+  // deleted.
+  //
+  // If zero, then the task age is unlimited.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  //
+  // `max_retry_duration` will be truncated to the nearest second.
+  //
+  // This field has the same meaning as
+  // [task_age_limit in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#retry_parameters).
+  google.protobuf.Duration max_retry_duration = 2;
+
+  // A task will be [scheduled][google.cloud.tasks.v2beta3.Task.schedule_time] for retry between
+  // [min_backoff][google.cloud.tasks.v2beta3.RetryConfig.min_backoff] and
+  // [max_backoff][google.cloud.tasks.v2beta3.RetryConfig.max_backoff] duration after it fails,
+  // if the queue's [RetryConfig][google.cloud.tasks.v2beta3.RetryConfig] specifies that the task should be
+  // retried.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  //
+  // `min_backoff` will be truncated to the nearest second.
+  //
+  // This field has the same meaning as
+  // [min_backoff_seconds in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#retry_parameters).
+  google.protobuf.Duration min_backoff = 3;
+
+  // A task will be [scheduled][google.cloud.tasks.v2beta3.Task.schedule_time] for retry between
+  // [min_backoff][google.cloud.tasks.v2beta3.RetryConfig.min_backoff] and
+  // [max_backoff][google.cloud.tasks.v2beta3.RetryConfig.max_backoff] duration after it fails,
+  // if the queue's [RetryConfig][google.cloud.tasks.v2beta3.RetryConfig] specifies that the task should be
+  // retried.
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  //
+  // `max_backoff` will be truncated to the nearest second.
+  //
+  // This field has the same meaning as
+  // [max_backoff_seconds in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#retry_parameters).
+  google.protobuf.Duration max_backoff = 4;
+
+  // The time between retries will double `max_doublings` times.
+  //
+  // A task's retry interval starts at
+  // [min_backoff][google.cloud.tasks.v2beta3.RetryConfig.min_backoff], then doubles
+  // `max_doublings` times, then increases linearly, and finally
+  // retries retries at intervals of
+  // [max_backoff][google.cloud.tasks.v2beta3.RetryConfig.max_backoff] up to
+  // [max_attempts][google.cloud.tasks.v2beta3.RetryConfig.max_attempts] times.
+  //
+  // For example, if [min_backoff][google.cloud.tasks.v2beta3.RetryConfig.min_backoff] is 10s,
+  // [max_backoff][google.cloud.tasks.v2beta3.RetryConfig.max_backoff] is 300s, and
+  // `max_doublings` is 3, then the a task will first be retried in
+  // 10s. The retry interval will double three times, and then
+  // increase linearly by 2^3 * 10s.  Finally, the task will retry at
+  // intervals of [max_backoff][google.cloud.tasks.v2beta3.RetryConfig.max_backoff] until the
+  // task has been attempted [max_attempts][google.cloud.tasks.v2beta3.RetryConfig.max_attempts]
+  // times. Thus, the requests will retry at 10s, 20s, 40s, 80s, 160s,
+  // 240s, 300s, 300s, ....
+  //
+  // If unspecified when the queue is created, Cloud Tasks will pick the
+  // default.
+  //
+  //
+  // This field has the same meaning as
+  // [max_doublings in queue.yaml/xml](https://cloud.google.com/appengine/docs/standard/python/config/queueref#retry_parameters).
+  int32 max_doublings = 5;
+}
diff --git a/tasks/google/cloud/tasks_v2beta3/proto/target.proto b/tasks/google/cloud/tasks_v2beta3/proto/target.proto
new file mode 100644
index 000000000000..087249f93d2c
--- /dev/null
+++ b/tasks/google/cloud/tasks_v2beta3/proto/target.proto
@@ -0,0 +1,282 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.tasks.v2beta3;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3;tasks";
+option java_multiple_files = true;
+option java_outer_classname = "TargetProto";
+option java_package = "com.google.cloud.tasks.v2beta3";
+
+
+// App Engine HTTP queue.
+//
+// The task will be delivered to the App Engine application hostname
+// specified by its [AppEngineHttpQueue][google.cloud.tasks.v2beta3.AppEngineHttpQueue] and [AppEngineHttpRequest][google.cloud.tasks.v2beta3.AppEngineHttpRequest].
+// The documentation for [AppEngineHttpRequest][google.cloud.tasks.v2beta3.AppEngineHttpRequest] explains how the
+// task's host URL is constructed.
+//
+// Using [AppEngineHttpQueue][google.cloud.tasks.v2beta3.AppEngineHttpQueue] requires
+// [`appengine.applications.get`](https://cloud.google.com/appengine/docs/admin-api/access-control)
+// Google IAM permission for the project
+// and the following scope:
+//
+// `https://www.googleapis.com/auth/cloud-platform`
+message AppEngineHttpQueue {
+  // Overrides for the
+  // [task-level app_engine_routing][google.cloud.tasks.v2beta3.AppEngineHttpRequest.app_engine_routing].
+  //
+  // If set, `app_engine_routing_override` is used for all tasks in
+  // the queue, no matter what the setting is for the
+  // [task-level app_engine_routing][google.cloud.tasks.v2beta3.AppEngineHttpRequest.app_engine_routing].
+  AppEngineRouting app_engine_routing_override = 1;
+}
+
+// App Engine HTTP request.
+//
+// The message defines the HTTP request that is sent to an App Engine app when
+// the task is dispatched.
+//
+// This proto can only be used for tasks in a queue which has
+// [app_engine_http_queue][google.cloud.tasks.v2beta3.Queue.app_engine_http_queue] set.
+//
+// Using [AppEngineHttpRequest][google.cloud.tasks.v2beta3.AppEngineHttpRequest] requires
+// [`appengine.applications.get`](https://cloud.google.com/appengine/docs/admin-api/access-control)
+// Google IAM permission for the project
+// and the following scope:
+//
+// `https://www.googleapis.com/auth/cloud-platform`
+//
+// The task will be delivered to the App Engine app which belongs to the same
+// project as the queue. For more information, see
+// [How Requests are Routed](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed)
+// and how routing is affected by
+// [dispatch files](https://cloud.google.com/appengine/docs/python/config/dispatchref).
+// Traffic is encrypted during transport and never leaves Google datacenters.
+// Because this traffic is carried over a communication mechanism internal to
+// Google, you cannot explicitly set the protocol (for example, HTTP or HTTPS).
+// The request to the handler, however, will appear to have used the HTTP
+// protocol.
+//
+// The [AppEngineRouting][google.cloud.tasks.v2beta3.AppEngineRouting] used to construct the URL that the task is
+// delivered to can be set at the queue-level or task-level:
+//
+// * If set,
+//    [app_engine_routing_override][google.cloud.tasks.v2beta3.AppEngineHttpQueue.app_engine_routing_override]
+//    is used for all tasks in the queue, no matter what the setting
+//    is for the
+//    [task-level app_engine_routing][google.cloud.tasks.v2beta3.AppEngineHttpRequest.app_engine_routing].
+//
+//
+// The `url` that the task will be sent to is:
+//
+// * `url =` [host][google.cloud.tasks.v2beta3.AppEngineRouting.host] `+`
+//   [relative_uri][google.cloud.tasks.v2beta3.AppEngineHttpRequest.relative_uri]
+//
+// Tasks can be dispatched to secure app handlers, unsecure app handlers, and
+// URIs restricted with
+// [`login: admin`](https://cloud.google.com/appengine/docs/standard/python/config/appref).
+// Because tasks are not run as any user, they cannot be dispatched to URIs
+// restricted with
+// [`login: required`](https://cloud.google.com/appengine/docs/standard/python/config/appref)
+// Task dispatches also do not follow redirects.
+//
+// The task attempt has succeeded if the app's request handler returns
+// an HTTP response code in the range [`200` - `299`]. `503` is
+// considered an App Engine system error instead of an application
+// error. Requests returning error `503` will be retried regardless of
+// retry configuration and not counted against retry counts.
+// Any other response code or a failure to receive a response before the
+// deadline is a failed attempt.
+message AppEngineHttpRequest {
+  // The HTTP method to use for the request. The default is POST.
+  //
+  // The app's request handler for the task's target URL must be able to handle
+  // HTTP requests with this http_method, otherwise the task attempt will fail
+  // with error code 405 (Method Not Allowed). See
+  // [Writing a push task request handler](https://cloud.google.com/appengine/docs/java/taskqueue/push/creating-handlers#writing_a_push_task_request_handler)
+  // and the documentation for the request handlers in the language your app is
+  // written in e.g.
+  // [Python Request Handler](https://cloud.google.com/appengine/docs/python/tools/webapp/requesthandlerclass).
+  HttpMethod http_method = 1;
+
+  // Task-level setting for App Engine routing.
+  //
+  // If set,
+  // [app_engine_routing_override][google.cloud.tasks.v2beta3.AppEngineHttpQueue.app_engine_routing_override]
+  // is used for all tasks in the queue, no matter what the setting is for the
+  // [task-level app_engine_routing][google.cloud.tasks.v2beta3.AppEngineHttpRequest.app_engine_routing].
+  AppEngineRouting app_engine_routing = 2;
+
+  // The relative URI.
+  //
+  // The relative URI must begin with "/" and must be a valid HTTP relative URI.
+  // It can contain a path and query string arguments.
+  // If the relative URI is empty, then the root path "/" will be used.
+  // No spaces are allowed, and the maximum length allowed is 2083 characters.
+  string relative_uri = 3;
+
+  // HTTP request headers.
+  //
+  // This map contains the header field names and values.
+  // Headers can be set when the
+  // [task is created][google.cloud.tasks.v2beta3.CloudTasks.CreateTask].
+  // Repeated headers are not supported but a header value can contain commas.
+  //
+  // Cloud Tasks sets some headers to default values:
+  //
+  // * `User-Agent`: By default, this header is
+  //   `"AppEngine-Google; (+http://code.google.com/appengine)"`.
+  //   This header can be modified, but Cloud Tasks will append
+  //   `"AppEngine-Google; (+http://code.google.com/appengine)"` to the
+  //   modified `User-Agent`.
+  //
+  // If the task has a [body][google.cloud.tasks.v2beta3.AppEngineHttpRequest.body], Cloud
+  // Tasks sets the following headers:
+  //
+  // * `Content-Type`: By default, the `Content-Type` header is set to
+  //   `"application/octet-stream"`. The default can be overridden by explicitly
+  //   setting `Content-Type` to a particular media type when the
+  //   [task is created][google.cloud.tasks.v2beta3.CloudTasks.CreateTask].
+  //   For example, `Content-Type` can be set to `"application/json"`.
+  // * `Content-Length`: This is computed by Cloud Tasks. This value is
+  //   output only.   It cannot be changed.
+  //
+  // The headers below cannot be set or overridden:
+  //
+  // * `Host`
+  // * `X-Google-*`
+  // * `X-AppEngine-*`
+  //
+  // In addition, Cloud Tasks sets some headers when the task is dispatched,
+  // such as headers containing information about the task; see
+  // [request headers](https://cloud.google.com/appengine/docs/python/taskqueue/push/creating-handlers#reading_request_headers).
+  // These headers are set only when the task is dispatched, so they are not
+  // visible when the task is returned in a Cloud Tasks response.
+  //
+  // Although there is no specific limit for the maximum number of headers or
+  // the size, there is a limit on the maximum size of the [Task][google.cloud.tasks.v2beta3.Task]. For more
+  // information, see the [CreateTask][google.cloud.tasks.v2beta3.CloudTasks.CreateTask] documentation.
+  map<string, string> headers = 4;
+
+  // HTTP request body.
+  //
+  // A request body is allowed only if the HTTP method is POST or PUT. It is
+  // an error to set a body on a task with an incompatible [HttpMethod][google.cloud.tasks.v2beta3.HttpMethod].
+  bytes body = 5;
+}
+
+// App Engine Routing.
+//
+// Defines routing characteristics specific to App Engine - service, version,
+// and instance.
+//
+// For more information about services, versions, and instances see
+// [An Overview of App Engine](https://cloud.google.com/appengine/docs/python/an-overview-of-app-engine),
+// [Microservices Architecture on Google App Engine](https://cloud.google.com/appengine/docs/python/microservices-on-app-engine),
+// [App Engine Standard request routing](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed),
+// and [App Engine Flex request routing](https://cloud.google.com/appengine/docs/flexible/python/how-requests-are-routed).
+message AppEngineRouting {
+  // App service.
+  //
+  // By default, the task is sent to the service which is the default
+  // service when the task is attempted.
+  //
+  // For some queues or tasks which were created using the App Engine
+  // Task Queue API, [host][google.cloud.tasks.v2beta3.AppEngineRouting.host] is not parsable
+  // into [service][google.cloud.tasks.v2beta3.AppEngineRouting.service],
+  // [version][google.cloud.tasks.v2beta3.AppEngineRouting.version], and
+  // [instance][google.cloud.tasks.v2beta3.AppEngineRouting.instance]. For example, some tasks
+  // which were created using the App Engine SDK use a custom domain
+  // name; custom domains are not parsed by Cloud Tasks. If
+  // [host][google.cloud.tasks.v2beta3.AppEngineRouting.host] is not parsable, then
+  // [service][google.cloud.tasks.v2beta3.AppEngineRouting.service],
+  // [version][google.cloud.tasks.v2beta3.AppEngineRouting.version], and
+  // [instance][google.cloud.tasks.v2beta3.AppEngineRouting.instance] are the empty string.
+  string service = 1;
+
+  // App version.
+  //
+  // By default, the task is sent to the version which is the default
+  // version when the task is attempted.
+  //
+  // For some queues or tasks which were created using the App Engine
+  // Task Queue API, [host][google.cloud.tasks.v2beta3.AppEngineRouting.host] is not parsable
+  // into [service][google.cloud.tasks.v2beta3.AppEngineRouting.service],
+  // [version][google.cloud.tasks.v2beta3.AppEngineRouting.version], and
+  // [instance][google.cloud.tasks.v2beta3.AppEngineRouting.instance]. For example, some tasks
+  // which were created using the App Engine SDK use a custom domain
+  // name; custom domains are not parsed by Cloud Tasks. If
+  // [host][google.cloud.tasks.v2beta3.AppEngineRouting.host] is not parsable, then
+  // [service][google.cloud.tasks.v2beta3.AppEngineRouting.service],
+  // [version][google.cloud.tasks.v2beta3.AppEngineRouting.version], and
+  // [instance][google.cloud.tasks.v2beta3.AppEngineRouting.instance] are the empty string.
+  string version = 2;
+
+  // App instance.
+  //
+  // By default, the task is sent to an instance which is available when
+  // the task is attempted.
+  //
+  // Requests can only be sent to a specific instance if
+  // [manual scaling is used in App Engine Standard](https://cloud.google.com/appengine/docs/python/an-overview-of-app-engine?hl=en_US#scaling_types_and_instance_classes).
+  // App Engine Flex does not support instances. For more information, see
+  // [App Engine Standard request routing](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed)
+  // and [App Engine Flex request routing](https://cloud.google.com/appengine/docs/flexible/python/how-requests-are-routed).
+  string instance = 3;
+
+  // Output only. The host that the task is sent to.
+  //
+  // The host is constructed from the domain name of the app associated with
+  // the queue's project ID (for example <app-id>.appspot.com), and the
+  // [service][google.cloud.tasks.v2beta3.AppEngineRouting.service], [version][google.cloud.tasks.v2beta3.AppEngineRouting.version],
+  // and [instance][google.cloud.tasks.v2beta3.AppEngineRouting.instance]. Tasks which were created using
+  // the App Engine SDK might have a custom domain name.
+  //
+  // For more information, see
+  // [How Requests are Routed](https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed).
+  string host = 4;
+}
+
+// The HTTP method used to execute the task.
+enum HttpMethod {
+  // HTTP method unspecified
+  HTTP_METHOD_UNSPECIFIED = 0;
+
+  // HTTP POST
+  POST = 1;
+
+  // HTTP GET
+  GET = 2;
+
+  // HTTP HEAD
+  HEAD = 3;
+
+  // HTTP PUT
+  PUT = 4;
+
+  // HTTP DELETE
+  DELETE = 5;
+
+  // HTTP PATCH
+  PATCH = 6;
+
+  // HTTP OPTIONS
+  OPTIONS = 7;
+}
diff --git a/tasks/google/cloud/tasks_v2beta3/proto/task.proto b/tasks/google/cloud/tasks_v2beta3/proto/task.proto
new file mode 100644
index 000000000000..46026f70e62f
--- /dev/null
+++ b/tasks/google/cloud/tasks_v2beta3/proto/task.proto
@@ -0,0 +1,179 @@
+// Copyright 2018 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.
+//
+
+syntax = "proto3";
+
+package google.cloud.tasks.v2beta3;
+
+import "google/api/annotations.proto";
+import "google/cloud/tasks/v2beta3/target.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3;tasks";
+option java_multiple_files = true;
+option java_outer_classname = "TaskProto";
+option java_package = "com.google.cloud.tasks.v2beta3";
+
+
+// A unit of scheduled work.
+message Task {
+  // The view specifies a subset of [Task][google.cloud.tasks.v2beta3.Task] data.
+  //
+  // When a task is returned in a response, not all
+  // information is retrieved by default because some data, such as
+  // payloads, might be desirable to return only when needed because
+  // of its large size or because of the sensitivity of data that it
+  // contains.
+  enum View {
+    // Unspecified. Defaults to BASIC.
+    VIEW_UNSPECIFIED = 0;
+
+    // The basic view omits fields which can be large or can contain
+    // sensitive data.
+    //
+    // This view does not include the
+    // [body in AppEngineHttpRequest][google.cloud.tasks.v2beta3.AppEngineHttpRequest.body].
+    // Bodies are desirable to return only when needed, because they
+    // can be large and because of the sensitivity of the data that you
+    // choose to store in it.
+    BASIC = 1;
+
+    // All information is returned.
+    //
+    // Authorization for [FULL][google.cloud.tasks.v2beta3.Task.View.FULL] requires
+    // `cloudtasks.tasks.fullView` [Google IAM](https://cloud.google.com/iam/)
+    // permission on the [Queue][google.cloud.tasks.v2beta3.Queue] resource.
+    FULL = 2;
+  }
+
+  // Optionally caller-specified in [CreateTask][google.cloud.tasks.v2beta3.CloudTasks.CreateTask].
+  //
+  // The task name.
+  //
+  // The task name must have the following format:
+  // `projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID`
+  //
+  // * `PROJECT_ID` can contain letters ([A-Za-z]), numbers ([0-9]),
+  //    hyphens (-), colons (:), or periods (.).
+  //    For more information, see
+  //    [Identifying projects](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects)
+  // * `LOCATION_ID` is the canonical ID for the task's location.
+  //    The list of available locations can be obtained by calling
+  //    [ListLocations][google.cloud.location.Locations.ListLocations].
+  //    For more information, see https://cloud.google.com/about/locations/.
+  // * `QUEUE_ID` can contain letters ([A-Za-z]), numbers ([0-9]), or
+  //   hyphens (-). The maximum length is 100 characters.
+  // * `TASK_ID` can contain only letters ([A-Za-z]), numbers ([0-9]),
+  //   hyphens (-), or underscores (_). The maximum length is 500 characters.
+  string name = 1;
+
+  // Required. The message to send to the worker.
+  oneof payload_type {
+    // HTTP request that is sent to the App Engine app handler.
+    //
+    // An App Engine task is a task that has [AppEngineHttpRequest][google.cloud.tasks.v2beta3.AppEngineHttpRequest] set.
+    AppEngineHttpRequest app_engine_http_request = 3;
+  }
+
+  // The time when the task is scheduled to be attempted.
+  //
+  // For App Engine queues, this is when the task will be attempted or retried.
+  //
+  // `schedule_time` will be truncated to the nearest microsecond.
+  google.protobuf.Timestamp schedule_time = 4;
+
+  // Output only. The time that the task was created.
+  //
+  // `create_time` will be truncated to the nearest second.
+  google.protobuf.Timestamp create_time = 5;
+
+  // The deadline for requests sent to the worker. If the worker does not
+  // respond by this deadline then the request is cancelled and the attempt
+  // is marked as a `DEADLINE_EXCEEDED` failure. Cloud Tasks will retry the
+  // task according to the [RetryConfig][google.cloud.tasks.v2beta3.RetryConfig].
+  //
+  // Note that when the request is cancelled, Cloud Tasks will stop listing for
+  // the response, but whether the worker stops processing depends on the
+  // worker. For example, if the worker is stuck, it may not react to cancelled
+  // requests.
+  //
+  // The default and maximum values depend on the type of request:
+  //
+  //
+  // * For [App Engine tasks][google.cloud.tasks.v2beta3.AppEngineHttpRequest], 0 indicates that the
+  //   request has the default deadline. The default deadline depends on the
+  //   [scaling type](https://cloud.google.com/appengine/docs/standard/go/how-instances-are-managed#instance_scaling)
+  //   of the service: 10 minutes for standard apps with automatic scaling, 24
+  //   hours for standard apps with manual and basic scaling, and 60 minutes for
+  //   flex apps. If the request deadline is set, it must be in the interval [15
+  //   seconds, 24 hours 15 seconds]. Regardless of the task's
+  //   `dispatch_deadline`, the app handler will not run for longer than than
+  //   the service's timeout. We recommend setting the `dispatch_deadline` to
+  //   at most a few seconds more than the app handler's timeout. For more
+  //   information see
+  //   [Timeouts](https://cloud.google.com/tasks/docs/creating-appengine-handlers#timeouts).
+  //
+  // `dispatch_deadline` will be truncated to the nearest millisecond. The
+  // deadline is an approximate deadline.
+  google.protobuf.Duration dispatch_deadline = 12;
+
+  // Output only. The number of attempts dispatched.
+  //
+  // This count includes tasks which have been dispatched but haven't
+  // received a response.
+  int32 dispatch_count = 6;
+
+  // Output only. The number of attempts which have received a response.
+  int32 response_count = 7;
+
+  // Output only. The status of the task's first attempt.
+  //
+  // Only [dispatch_time][google.cloud.tasks.v2beta3.Attempt.dispatch_time] will be set.
+  // The other [Attempt][google.cloud.tasks.v2beta3.Attempt] information is not retained by Cloud Tasks.
+  Attempt first_attempt = 8;
+
+  // Output only. The status of the task's last attempt.
+  Attempt last_attempt = 9;
+
+  // Output only. The view specifies which subset of the [Task][google.cloud.tasks.v2beta3.Task] has
+  // been returned.
+  View view = 10;
+}
+
+// The status of a task attempt.
+message Attempt {
+  // Output only. The time that this attempt was scheduled.
+  //
+  // `schedule_time` will be truncated to the nearest microsecond.
+  google.protobuf.Timestamp schedule_time = 1;
+
+  // Output only. The time that this attempt was dispatched.
+  //
+  // `dispatch_time` will be truncated to the nearest microsecond.
+  google.protobuf.Timestamp dispatch_time = 2;
+
+  // Output only. The time that this attempt response was received.
+  //
+  // `response_time` will be truncated to the nearest microsecond.
+  google.protobuf.Timestamp response_time = 3;
+
+  // Output only. The response from the worker for this attempt.
+  //
+  // If `response_time` is unset, then the task has not been attempted or is
+  // currently running and the `response_status` field is meaningless.
+  google.rpc.Status response_status = 4;
+}
diff --git a/tasks/synth.metadata b/tasks/synth.metadata
index cdc6de7a5ae8..832d77255cf9 100644
--- a/tasks/synth.metadata
+++ b/tasks/synth.metadata
@@ -1,5 +1,5 @@
 {
-  "updateTime": "2019-01-26T13:31:23.684371Z",
+  "updateTime": "2019-01-29T17:48:41.546861Z",
   "sources": [
     {
       "generator": {
@@ -12,8 +12,8 @@
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "a6b4398490269577fc511f297b85763ba4701403",
-        "internalRef": "230969086"
+        "sha": "3cdb7227019524e7963071cf80a9624bf055b284",
+        "internalRef": "231246006"
       }
     },
     {
diff --git a/tasks/synth.py b/tasks/synth.py
index 5d3c523c899b..b61df3478790 100644
--- a/tasks/synth.py
+++ b/tasks/synth.py
@@ -29,7 +29,10 @@
 # ----------------------------------------------------------------------------
 for version in ["v2beta2", "v2beta3"]:
     library = gapic.py_library(
-        "tasks", version, config_path=f"artman_cloudtasks_{version}.yaml"
+        "tasks",
+        version,
+        config_path=f"artman_cloudtasks_{version}.yaml",
+        include_protos=True,
     )
 
     s.copy(library, excludes=excludes)
@@ -68,7 +71,7 @@
     "\g<1>...             'service': 'default',\n"
     "\g<1>...         },\n"
     "\g<1>...     },\n"
-    "\g<1>... }\n"
+    "\g<1>... }\n",
 )
 
 
diff --git a/texttospeech/google/cloud/texttospeech_v1/proto/cloud_tts.proto b/texttospeech/google/cloud/texttospeech_v1/proto/cloud_tts.proto
new file mode 100644
index 000000000000..2afe1a8b7dee
--- /dev/null
+++ b/texttospeech/google/cloud/texttospeech_v1/proto/cloud_tts.proto
@@ -0,0 +1,228 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.texttospeech.v1beta1;
+
+import "google/api/annotations.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/texttospeech/v1beta1;texttospeech";
+option java_multiple_files = true;
+option java_outer_classname = "TextToSpeechProto";
+option java_package = "com.google.cloud.texttospeech.v1beta1";
+
+
+// Service that implements Google Cloud Text-to-Speech API.
+service TextToSpeech {
+  // Returns a list of [Voice][google.cloud.texttospeech.v1beta1.Voice]
+  // supported for synthesis.
+  rpc ListVoices(ListVoicesRequest) returns (ListVoicesResponse) {
+    option (google.api.http) = {
+      get: "/v1beta1/voices"
+    };
+  }
+
+  // Synthesizes speech synchronously: receive results after all text input
+  // has been processed.
+  rpc SynthesizeSpeech(SynthesizeSpeechRequest) returns (SynthesizeSpeechResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/text:synthesize"
+      body: "*"
+    };
+  }
+}
+
+// The top-level message sent by the client for the `ListVoices` method.
+message ListVoicesRequest {
+  // Optional (but recommended)
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag. If
+  // specified, the ListVoices call will only return voices that can be used to
+  // synthesize this language_code. E.g. when specifying "en-NZ", you will get
+  // supported "en-*" voices; when specifying "no", you will get supported
+  // "no-*" (Norwegian) and "nb-*" (Norwegian Bokmal) voices; specifying "zh"
+  // will also get supported "cmn-*" voices; specifying "zh-hk" will also get
+  // supported "yue-*" voices.
+  string language_code = 1;
+}
+
+// The message returned to the client by the `ListVoices` method.
+message ListVoicesResponse {
+  // The list of voices.
+  repeated Voice voices = 1;
+}
+
+// Description of a voice supported by the TTS service.
+message Voice {
+  // The languages that this voice supports, expressed as
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tags (e.g.
+  // "en-US", "es-419", "cmn-tw").
+  repeated string language_codes = 1;
+
+  // The name of this voice.  Each distinct voice has a unique name.
+  string name = 2;
+
+  // The gender of this voice.
+  SsmlVoiceGender ssml_gender = 3;
+
+  // The natural sample rate (in hertz) for this voice.
+  int32 natural_sample_rate_hertz = 4;
+}
+
+// The top-level message sent by the client for the `SynthesizeSpeech` method.
+message SynthesizeSpeechRequest {
+  // Required. The Synthesizer requires either plain text or SSML as input.
+  SynthesisInput input = 1;
+
+  // Required. The desired voice of the synthesized audio.
+  VoiceSelectionParams voice = 2;
+
+  // Required. The configuration of the synthesized audio.
+  AudioConfig audio_config = 3;
+}
+
+// Contains text input to be synthesized. Either `text` or `ssml` must be
+// supplied. Supplying both or neither returns
+// [google.rpc.Code.INVALID_ARGUMENT][]. The input size is limited to 5000
+// characters.
+message SynthesisInput {
+  // The input source, which is either plain text or SSML.
+  oneof input_source {
+    // The raw text to be synthesized.
+    string text = 1;
+
+    // The SSML document to be synthesized. The SSML document must be valid
+    // and well-formed. Otherwise the RPC will fail and return
+    // [google.rpc.Code.INVALID_ARGUMENT][]. For more information, see
+    // [SSML](/speech/text-to-speech/docs/ssml).
+    string ssml = 2;
+  }
+}
+
+// Description of which voice to use for a synthesis request.
+message VoiceSelectionParams {
+  // The language (and optionally also the region) of the voice expressed as a
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag, e.g.
+  // "en-US". Required. This should not include a script tag (e.g. use
+  // "cmn-cn" rather than "cmn-Hant-cn"), because the script will be inferred
+  // from the input provided in the SynthesisInput.  The TTS service
+  // will use this parameter to help choose an appropriate voice.  Note that
+  // the TTS service may choose a voice with a slightly different language code
+  // than the one selected; it may substitute a different region
+  // (e.g. using en-US rather than en-CA if there isn't a Canadian voice
+  // available), or even a different language, e.g. using "nb" (Norwegian
+  // Bokmal) instead of "no" (Norwegian)".
+  string language_code = 1;
+
+  // The name of the voice. Optional; if not set, the service will choose a
+  // voice based on the other parameters such as language_code and gender.
+  string name = 2;
+
+  // The preferred gender of the voice. Optional; if not set, the service will
+  // choose a voice based on the other parameters such as language_code and
+  // name. Note that this is only a preference, not requirement; if a
+  // voice of the appropriate gender is not available, the synthesizer should
+  // substitute a voice with a different gender rather than failing the request.
+  SsmlVoiceGender ssml_gender = 3;
+}
+
+// Description of audio data to be synthesized.
+message AudioConfig {
+  // Required. The format of the requested audio byte stream.
+  AudioEncoding audio_encoding = 1;
+
+  // Optional speaking rate/speed, in the range [0.25, 4.0]. 1.0 is the normal
+  // native speed supported by the specific voice. 2.0 is twice as fast, and
+  // 0.5 is half as fast. If unset(0.0), defaults to the native 1.0 speed. Any
+  // other values < 0.25 or > 4.0 will return an error.
+  double speaking_rate = 2;
+
+  // Optional speaking pitch, in the range [-20.0, 20.0]. 20 means increase 20
+  // semitones from the original pitch. -20 means decrease 20 semitones from the
+  // original pitch.
+  double pitch = 3;
+
+  // Optional volume gain (in dB) of the normal native volume supported by the
+  // specific voice, in the range [-96.0, 16.0]. If unset, or set to a value of
+  // 0.0 (dB), will play at normal native signal amplitude. A value of -6.0 (dB)
+  // will play at approximately half the amplitude of the normal native signal
+  // amplitude. A value of +6.0 (dB) will play at approximately twice the
+  // amplitude of the normal native signal amplitude. Strongly recommend not to
+  // exceed +10 (dB) as there's usually no effective increase in loudness for
+  // any value greater than that.
+  double volume_gain_db = 4;
+
+  // The synthesis sample rate (in hertz) for this audio. Optional.  If this is
+  // different from the voice's natural sample rate, then the synthesizer will
+  // honor this request by converting to the desired sample rate (which might
+  // result in worse audio quality), unless the specified sample rate is not
+  // supported for the encoding chosen, in which case it will fail the request
+  // and return [google.rpc.Code.INVALID_ARGUMENT][].
+  int32 sample_rate_hertz = 5;
+
+  // An identifier which selects 'audio effects' profiles that are applied on
+  // (post synthesized) text to speech.
+  // Effects are applied on top of each other in the order they are given.
+  repeated string effects_profile_id = 6;
+}
+
+// The message returned to the client by the `SynthesizeSpeech` method.
+message SynthesizeSpeechResponse {
+  // The audio data bytes encoded as specified in the request, including the
+  // header (For LINEAR16 audio, we include the WAV header). Note: as
+  // with all bytes fields, protobuffers use a pure binary representation,
+  // whereas JSON representations use base64.
+  bytes audio_content = 1;
+}
+
+// Gender of the voice as described in
+// [SSML voice element](https://www.w3.org/TR/speech-synthesis11/#edef_voice).
+enum SsmlVoiceGender {
+  // An unspecified gender.
+  // In VoiceSelectionParams, this means that the client doesn't care which
+  // gender the selected voice will have. In the Voice field of
+  // ListVoicesResponse, this may mean that the voice doesn't fit any of the
+  // other categories in this enum, or that the gender of the voice isn't known.
+  SSML_VOICE_GENDER_UNSPECIFIED = 0;
+
+  // A male voice.
+  MALE = 1;
+
+  // A female voice.
+  FEMALE = 2;
+
+  // A gender-neutral voice.
+  NEUTRAL = 3;
+}
+
+// Configuration to set up audio encoder. The encoding determines the output
+// audio format that we'd like.
+enum AudioEncoding {
+  // Not specified. Will return result [google.rpc.Code.INVALID_ARGUMENT][].
+  AUDIO_ENCODING_UNSPECIFIED = 0;
+
+  // Uncompressed 16-bit signed little-endian samples (Linear PCM).
+  // Audio content returned as LINEAR16 also contains a WAV header.
+  LINEAR16 = 1;
+
+  // MP3 audio.
+  MP3 = 2;
+
+  // Opus encoded audio wrapped in an ogg container. The result will be a
+  // file which can be played natively on Android, and in browsers (at least
+  // Chrome and Firefox). The quality of the encoding is considerably higher
+  // than MP3 while using approximately the same bitrate.
+  OGG_OPUS = 3;
+}
diff --git a/texttospeech/google/cloud/texttospeech_v1beta1/proto/cloud_tts.proto b/texttospeech/google/cloud/texttospeech_v1beta1/proto/cloud_tts.proto
new file mode 100644
index 000000000000..2afe1a8b7dee
--- /dev/null
+++ b/texttospeech/google/cloud/texttospeech_v1beta1/proto/cloud_tts.proto
@@ -0,0 +1,228 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.texttospeech.v1beta1;
+
+import "google/api/annotations.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/texttospeech/v1beta1;texttospeech";
+option java_multiple_files = true;
+option java_outer_classname = "TextToSpeechProto";
+option java_package = "com.google.cloud.texttospeech.v1beta1";
+
+
+// Service that implements Google Cloud Text-to-Speech API.
+service TextToSpeech {
+  // Returns a list of [Voice][google.cloud.texttospeech.v1beta1.Voice]
+  // supported for synthesis.
+  rpc ListVoices(ListVoicesRequest) returns (ListVoicesResponse) {
+    option (google.api.http) = {
+      get: "/v1beta1/voices"
+    };
+  }
+
+  // Synthesizes speech synchronously: receive results after all text input
+  // has been processed.
+  rpc SynthesizeSpeech(SynthesizeSpeechRequest) returns (SynthesizeSpeechResponse) {
+    option (google.api.http) = {
+      post: "/v1beta1/text:synthesize"
+      body: "*"
+    };
+  }
+}
+
+// The top-level message sent by the client for the `ListVoices` method.
+message ListVoicesRequest {
+  // Optional (but recommended)
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag. If
+  // specified, the ListVoices call will only return voices that can be used to
+  // synthesize this language_code. E.g. when specifying "en-NZ", you will get
+  // supported "en-*" voices; when specifying "no", you will get supported
+  // "no-*" (Norwegian) and "nb-*" (Norwegian Bokmal) voices; specifying "zh"
+  // will also get supported "cmn-*" voices; specifying "zh-hk" will also get
+  // supported "yue-*" voices.
+  string language_code = 1;
+}
+
+// The message returned to the client by the `ListVoices` method.
+message ListVoicesResponse {
+  // The list of voices.
+  repeated Voice voices = 1;
+}
+
+// Description of a voice supported by the TTS service.
+message Voice {
+  // The languages that this voice supports, expressed as
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tags (e.g.
+  // "en-US", "es-419", "cmn-tw").
+  repeated string language_codes = 1;
+
+  // The name of this voice.  Each distinct voice has a unique name.
+  string name = 2;
+
+  // The gender of this voice.
+  SsmlVoiceGender ssml_gender = 3;
+
+  // The natural sample rate (in hertz) for this voice.
+  int32 natural_sample_rate_hertz = 4;
+}
+
+// The top-level message sent by the client for the `SynthesizeSpeech` method.
+message SynthesizeSpeechRequest {
+  // Required. The Synthesizer requires either plain text or SSML as input.
+  SynthesisInput input = 1;
+
+  // Required. The desired voice of the synthesized audio.
+  VoiceSelectionParams voice = 2;
+
+  // Required. The configuration of the synthesized audio.
+  AudioConfig audio_config = 3;
+}
+
+// Contains text input to be synthesized. Either `text` or `ssml` must be
+// supplied. Supplying both or neither returns
+// [google.rpc.Code.INVALID_ARGUMENT][]. The input size is limited to 5000
+// characters.
+message SynthesisInput {
+  // The input source, which is either plain text or SSML.
+  oneof input_source {
+    // The raw text to be synthesized.
+    string text = 1;
+
+    // The SSML document to be synthesized. The SSML document must be valid
+    // and well-formed. Otherwise the RPC will fail and return
+    // [google.rpc.Code.INVALID_ARGUMENT][]. For more information, see
+    // [SSML](/speech/text-to-speech/docs/ssml).
+    string ssml = 2;
+  }
+}
+
+// Description of which voice to use for a synthesis request.
+message VoiceSelectionParams {
+  // The language (and optionally also the region) of the voice expressed as a
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag, e.g.
+  // "en-US". Required. This should not include a script tag (e.g. use
+  // "cmn-cn" rather than "cmn-Hant-cn"), because the script will be inferred
+  // from the input provided in the SynthesisInput.  The TTS service
+  // will use this parameter to help choose an appropriate voice.  Note that
+  // the TTS service may choose a voice with a slightly different language code
+  // than the one selected; it may substitute a different region
+  // (e.g. using en-US rather than en-CA if there isn't a Canadian voice
+  // available), or even a different language, e.g. using "nb" (Norwegian
+  // Bokmal) instead of "no" (Norwegian)".
+  string language_code = 1;
+
+  // The name of the voice. Optional; if not set, the service will choose a
+  // voice based on the other parameters such as language_code and gender.
+  string name = 2;
+
+  // The preferred gender of the voice. Optional; if not set, the service will
+  // choose a voice based on the other parameters such as language_code and
+  // name. Note that this is only a preference, not requirement; if a
+  // voice of the appropriate gender is not available, the synthesizer should
+  // substitute a voice with a different gender rather than failing the request.
+  SsmlVoiceGender ssml_gender = 3;
+}
+
+// Description of audio data to be synthesized.
+message AudioConfig {
+  // Required. The format of the requested audio byte stream.
+  AudioEncoding audio_encoding = 1;
+
+  // Optional speaking rate/speed, in the range [0.25, 4.0]. 1.0 is the normal
+  // native speed supported by the specific voice. 2.0 is twice as fast, and
+  // 0.5 is half as fast. If unset(0.0), defaults to the native 1.0 speed. Any
+  // other values < 0.25 or > 4.0 will return an error.
+  double speaking_rate = 2;
+
+  // Optional speaking pitch, in the range [-20.0, 20.0]. 20 means increase 20
+  // semitones from the original pitch. -20 means decrease 20 semitones from the
+  // original pitch.
+  double pitch = 3;
+
+  // Optional volume gain (in dB) of the normal native volume supported by the
+  // specific voice, in the range [-96.0, 16.0]. If unset, or set to a value of
+  // 0.0 (dB), will play at normal native signal amplitude. A value of -6.0 (dB)
+  // will play at approximately half the amplitude of the normal native signal
+  // amplitude. A value of +6.0 (dB) will play at approximately twice the
+  // amplitude of the normal native signal amplitude. Strongly recommend not to
+  // exceed +10 (dB) as there's usually no effective increase in loudness for
+  // any value greater than that.
+  double volume_gain_db = 4;
+
+  // The synthesis sample rate (in hertz) for this audio. Optional.  If this is
+  // different from the voice's natural sample rate, then the synthesizer will
+  // honor this request by converting to the desired sample rate (which might
+  // result in worse audio quality), unless the specified sample rate is not
+  // supported for the encoding chosen, in which case it will fail the request
+  // and return [google.rpc.Code.INVALID_ARGUMENT][].
+  int32 sample_rate_hertz = 5;
+
+  // An identifier which selects 'audio effects' profiles that are applied on
+  // (post synthesized) text to speech.
+  // Effects are applied on top of each other in the order they are given.
+  repeated string effects_profile_id = 6;
+}
+
+// The message returned to the client by the `SynthesizeSpeech` method.
+message SynthesizeSpeechResponse {
+  // The audio data bytes encoded as specified in the request, including the
+  // header (For LINEAR16 audio, we include the WAV header). Note: as
+  // with all bytes fields, protobuffers use a pure binary representation,
+  // whereas JSON representations use base64.
+  bytes audio_content = 1;
+}
+
+// Gender of the voice as described in
+// [SSML voice element](https://www.w3.org/TR/speech-synthesis11/#edef_voice).
+enum SsmlVoiceGender {
+  // An unspecified gender.
+  // In VoiceSelectionParams, this means that the client doesn't care which
+  // gender the selected voice will have. In the Voice field of
+  // ListVoicesResponse, this may mean that the voice doesn't fit any of the
+  // other categories in this enum, or that the gender of the voice isn't known.
+  SSML_VOICE_GENDER_UNSPECIFIED = 0;
+
+  // A male voice.
+  MALE = 1;
+
+  // A female voice.
+  FEMALE = 2;
+
+  // A gender-neutral voice.
+  NEUTRAL = 3;
+}
+
+// Configuration to set up audio encoder. The encoding determines the output
+// audio format that we'd like.
+enum AudioEncoding {
+  // Not specified. Will return result [google.rpc.Code.INVALID_ARGUMENT][].
+  AUDIO_ENCODING_UNSPECIFIED = 0;
+
+  // Uncompressed 16-bit signed little-endian samples (Linear PCM).
+  // Audio content returned as LINEAR16 also contains a WAV header.
+  LINEAR16 = 1;
+
+  // MP3 audio.
+  MP3 = 2;
+
+  // Opus encoded audio wrapped in an ogg container. The result will be a
+  // file which can be played natively on Android, and in browsers (at least
+  // Chrome and Firefox). The quality of the encoding is considerably higher
+  // than MP3 while using approximately the same bitrate.
+  OGG_OPUS = 3;
+}
diff --git a/texttospeech/synth.metadata b/texttospeech/synth.metadata
index c1b7282b6b6d..e9f21b74b8c1 100644
--- a/texttospeech/synth.metadata
+++ b/texttospeech/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:29:49.053899Z",
+  "updateTime": "2019-01-24T17:39:41.039359Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/texttospeech/synth.py b/texttospeech/synth.py
index ae28fac39190..d03c792a0888 100644
--- a/texttospeech/synth.py
+++ b/texttospeech/synth.py
@@ -26,7 +26,7 @@
 # Generate texttospeech GAPIC layer
 # ----------------------------------------------------------------------------
 for version in versions:
-    library = gapic.py_library("texttospeech", version)
+    library = gapic.py_library("texttospeech", version, include_protos=True)
     s.move(library / f"google/cloud/texttospeech_{version}")
     s.move(library / f"tests/unit/gapic/{version}")
     s.move(library / f"docs/gapic/{version}")
diff --git a/trace/google/cloud/trace_v1/proto/trace.proto b/trace/google/cloud/trace_v1/proto/trace.proto
new file mode 100644
index 000000000000..aaa5ade0be56
--- /dev/null
+++ b/trace/google/cloud/trace_v1/proto/trace.proto
@@ -0,0 +1,336 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.devtools.cloudtrace.v2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/wrappers.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.Trace.V2";
+option go_package = "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2;cloudtrace";
+option java_multiple_files = true;
+option java_outer_classname = "TraceProto";
+option java_package = "com.google.devtools.cloudtrace.v2";
+option php_namespace = "Google\\Cloud\\Trace\\V2";
+
+
+// A span represents a single operation within a trace. Spans can be
+// nested to form a trace tree. Often, a trace contains a root span
+// that describes the end-to-end latency, and one or more subspans for
+// its sub-operations. A trace can also contain multiple root spans,
+// or none at all. Spans do not need to be contiguous&mdash;there may be
+// gaps or overlaps between spans in a trace.
+message Span {
+  // A set of attributes, each in the format `[KEY]:[VALUE]`.
+  message Attributes {
+    // The set of attributes. Each attribute's key can be up to 128 bytes
+    // long. The value can be a string up to 256 bytes, an integer, or the
+    // Boolean values `true` and `false`. For example:
+    //
+    //     "/instance_id": "my-instance"
+    //     "/http/user_agent": ""
+    //     "/http/request_bytes": 300
+    //     "abc.com/myattribute": true
+    map<string, AttributeValue> attribute_map = 1;
+
+    // The number of attributes that were discarded. Attributes can be discarded
+    // because their keys are too long or because there are too many attributes.
+    // If this value is 0 then all attributes are valid.
+    int32 dropped_attributes_count = 2;
+  }
+
+  // A time-stamped annotation or message event in the Span.
+  message TimeEvent {
+    // Text annotation with a set of attributes.
+    message Annotation {
+      // A user-supplied message describing the event. The maximum length for
+      // the description is 256 bytes.
+      TruncatableString description = 1;
+
+      // A set of attributes on the annotation. You can have up to 4 attributes
+      // per Annotation.
+      Attributes attributes = 2;
+    }
+
+    // An event describing a message sent/received between Spans.
+    message MessageEvent {
+      // Indicates whether the message was sent or received.
+      enum Type {
+        // Unknown event type.
+        TYPE_UNSPECIFIED = 0;
+
+        // Indicates a sent message.
+        SENT = 1;
+
+        // Indicates a received message.
+        RECEIVED = 2;
+      }
+
+      // Type of MessageEvent. Indicates whether the message was sent or
+      // received.
+      Type type = 1;
+
+      // An identifier for the MessageEvent's message that can be used to match
+      // SENT and RECEIVED MessageEvents. It is recommended to be unique within
+      // a Span.
+      int64 id = 2;
+
+      // The number of uncompressed bytes sent or received.
+      int64 uncompressed_size_bytes = 3;
+
+      // The number of compressed bytes sent or received. If missing assumed to
+      // be the same size as uncompressed.
+      int64 compressed_size_bytes = 4;
+    }
+
+    // The timestamp indicating the time the event occurred.
+    google.protobuf.Timestamp time = 1;
+
+    // A `TimeEvent` can contain either an `Annotation` object or a
+    // `MessageEvent` object, but not both.
+    oneof value {
+      // Text annotation with a set of attributes.
+      Annotation annotation = 2;
+
+      // An event describing a message sent/received between Spans.
+      MessageEvent message_event = 3;
+    }
+  }
+
+  // A collection of `TimeEvent`s. A `TimeEvent` is a time-stamped annotation
+  // on the span, consisting of either user-supplied key:value pairs, or
+  // details of a message sent/received between Spans.
+  message TimeEvents {
+    // A collection of `TimeEvent`s.
+    repeated TimeEvent time_event = 1;
+
+    // The number of dropped annotations in all the included time events.
+    // If the value is 0, then no annotations were dropped.
+    int32 dropped_annotations_count = 2;
+
+    // The number of dropped message events in all the included time events.
+    // If the value is 0, then no message events were dropped.
+    int32 dropped_message_events_count = 3;
+  }
+
+  // A pointer from the current span to another span in the same trace or in a
+  // different trace. For example, this can be used in batching operations,
+  // where a single batch handler processes multiple requests from different
+  // traces or when the handler receives a request from a different project.
+  message Link {
+    // The relationship of the current span relative to the linked span: child,
+    // parent, or unspecified.
+    enum Type {
+      // The relationship of the two spans is unknown.
+      TYPE_UNSPECIFIED = 0;
+
+      // The linked span is a child of the current span.
+      CHILD_LINKED_SPAN = 1;
+
+      // The linked span is a parent of the current span.
+      PARENT_LINKED_SPAN = 2;
+    }
+
+    // The [TRACE_ID] for a trace within a project.
+    string trace_id = 1;
+
+    // The [SPAN_ID] for a span within a trace.
+    string span_id = 2;
+
+    // The relationship of the current span relative to the linked span.
+    Type type = 3;
+
+    // A set of attributes on the link. You have have up to  32 attributes per
+    // link.
+    Attributes attributes = 4;
+  }
+
+  // A collection of links, which are references from this span to a span
+  // in the same or different trace.
+  message Links {
+    // A collection of links.
+    repeated Link link = 1;
+
+    // The number of dropped links after the maximum size was enforced. If
+    // this value is 0, then no links were dropped.
+    int32 dropped_links_count = 2;
+  }
+
+  // The resource name of the span in the following format:
+  //
+  //     projects/[PROJECT_ID]/traces/[TRACE_ID]/spans/[SPAN_ID]
+  //
+  // [TRACE_ID] is a unique identifier for a trace within a project;
+  // it is a 32-character hexadecimal encoding of a 16-byte array.
+  //
+  // [SPAN_ID] is a unique identifier for a span within a trace; it
+  // is a 16-character hexadecimal encoding of an 8-byte array.
+  string name = 1;
+
+  // The [SPAN_ID] portion of the span's resource name.
+  string span_id = 2;
+
+  // The [SPAN_ID] of this span's parent span. If this is a root span,
+  // then this field must be empty.
+  string parent_span_id = 3;
+
+  // A description of the span's operation (up to 128 bytes).
+  // Stackdriver Trace displays the description in the
+  // {% dynamic print site_values.console_name %}.
+  // For example, the display name can be a qualified method name or a file name
+  // and a line number where the operation is called. A best practice is to use
+  // the same display name within an application and at the same call point.
+  // This makes it easier to correlate spans in different traces.
+  TruncatableString display_name = 4;
+
+  // The start time of the span. On the client side, this is the time kept by
+  // the local machine where the span execution starts. On the server side, this
+  // is the time when the server's application handler starts running.
+  google.protobuf.Timestamp start_time = 5;
+
+  // The end time of the span. On the client side, this is the time kept by
+  // the local machine where the span execution ends. On the server side, this
+  // is the time when the server application handler stops running.
+  google.protobuf.Timestamp end_time = 6;
+
+  // A set of attributes on the span. You can have up to 32 attributes per
+  // span.
+  Attributes attributes = 7;
+
+  // Stack trace captured at the start of the span.
+  StackTrace stack_trace = 8;
+
+  // A set of time events. You can have up to 32 annotations and 128 message
+  // events per span.
+  TimeEvents time_events = 9;
+
+  // Links associated with the span. You can have up to 128 links per Span.
+  Links links = 10;
+
+  // An optional final status for this span.
+  google.rpc.Status status = 11;
+
+  // (Optional) Set this parameter to indicate whether this span is in
+  // the same process as its parent. If you do not set this parameter,
+  // Stackdriver Trace is unable to take advantage of this helpful
+  // information.
+  google.protobuf.BoolValue same_process_as_parent_span = 12;
+
+  // An optional number of child spans that were generated while this span
+  // was active. If set, allows implementation to detect missing child spans.
+  google.protobuf.Int32Value child_span_count = 13;
+}
+
+// The allowed types for [VALUE] in a `[KEY]:[VALUE]` attribute.
+message AttributeValue {
+  // The type of the value.
+  oneof value {
+    // A string up to 256 bytes long.
+    TruncatableString string_value = 1;
+
+    // A 64-bit signed integer.
+    int64 int_value = 2;
+
+    // A Boolean value represented by `true` or `false`.
+    bool bool_value = 3;
+  }
+}
+
+// A call stack appearing in a trace.
+message StackTrace {
+  // Represents a single stack frame in a stack trace.
+  message StackFrame {
+    // The fully-qualified name that uniquely identifies the function or
+    // method that is active in this frame (up to 1024 bytes).
+    TruncatableString function_name = 1;
+
+    // An un-mangled function name, if `function_name` is
+    // [mangled](http://www.avabodh.com/cxxin/namemangling.html). The name can
+    // be fully-qualified (up to 1024 bytes).
+    TruncatableString original_function_name = 2;
+
+    // The name of the source file where the function call appears (up to 256
+    // bytes).
+    TruncatableString file_name = 3;
+
+    // The line number in `file_name` where the function call appears.
+    int64 line_number = 4;
+
+    // The column number where the function call appears, if available.
+    // This is important in JavaScript because of its anonymous functions.
+    int64 column_number = 5;
+
+    // The binary module from where the code was loaded.
+    Module load_module = 6;
+
+    // The version of the deployed source code (up to 128 bytes).
+    TruncatableString source_version = 7;
+  }
+
+  // A collection of stack frames, which can be truncated.
+  message StackFrames {
+    // Stack frames in this call stack.
+    repeated StackFrame frame = 1;
+
+    // The number of stack frames that were dropped because there
+    // were too many stack frames.
+    // If this value is 0, then no stack frames were dropped.
+    int32 dropped_frames_count = 2;
+  }
+
+  // Stack frames in this stack trace. A maximum of 128 frames are allowed.
+  StackFrames stack_frames = 1;
+
+  // The hash ID is used to conserve network bandwidth for duplicate
+  // stack traces within a single trace.
+  //
+  // Often multiple spans will have identical stack traces.
+  // The first occurrence of a stack trace should contain both the
+  // `stackFrame` content and a value in `stackTraceHashId`.
+  //
+  // Subsequent spans within the same request can refer
+  // to that stack trace by only setting `stackTraceHashId`.
+  int64 stack_trace_hash_id = 2;
+}
+
+// Binary module.
+message Module {
+  // For example: main binary, kernel modules, and dynamic libraries
+  // such as libc.so, sharedlib.so (up to 256 bytes).
+  TruncatableString module = 1;
+
+  // A unique identifier for the module, usually a hash of its
+  // contents (up to 128 bytes).
+  TruncatableString build_id = 2;
+}
+
+// Represents a string that might be shortened to a specified length.
+message TruncatableString {
+  // The shortened string. For example, if the original string is 500
+  // bytes long and the limit of the string is 128 bytes, then
+  // `value` contains the first 128 bytes of the 500-byte string.
+  //
+  // Truncation always happens on a UTF8 character boundary. If there
+  // are multi-byte characters in the string, then the length of the
+  // shortened string might be less than the size limit.
+  string value = 1;
+
+  // The number of bytes removed from the original string. If this
+  // value is 0, then the string was not shortened.
+  int32 truncated_byte_count = 2;
+}
diff --git a/trace/google/cloud/trace_v1/proto/trace_pb2.py b/trace/google/cloud/trace_v1/proto/trace_pb2.py
index 25ac2a5cf6d9..d25b979c35dc 100644
--- a/trace/google/cloud/trace_v1/proto/trace_pb2.py
+++ b/trace/google/cloud/trace_v1/proto/trace_pb2.py
@@ -1083,3 +1083,4 @@
 DESCRIPTOR.services_by_name["TraceService"] = _TRACESERVICE
 
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/trace/google/cloud/trace_v1/proto/tracing.proto b/trace/google/cloud/trace_v1/proto/tracing.proto
new file mode 100644
index 000000000000..fd4f3e027771
--- /dev/null
+++ b/trace/google/cloud/trace_v1/proto/tracing.proto
@@ -0,0 +1,59 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.devtools.cloudtrace.v2;
+
+import "google/api/annotations.proto";
+import "google/devtools/cloudtrace/v2/trace.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Trace.V2";
+option go_package = "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2;cloudtrace";
+option java_multiple_files = true;
+option java_outer_classname = "TracingProto";
+option java_package = "com.google.devtools.cloudtrace.v2";
+option php_namespace = "Google\\Cloud\\Trace\\V2";
+
+
+// This file describes an API for collecting and viewing traces and spans
+// within a trace.  A Trace is a collection of spans corresponding to a single
+// operation or set of operations for an application. A span is an individual
+// timed event which forms a node of the trace tree. A single trace may
+// contain span(s) from multiple services.
+service TraceService {
+  // Sends new spans to new or existing traces. You cannot update
+  // existing spans.
+  rpc BatchWriteSpans(BatchWriteSpansRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { post: "/v2/{name=projects/*}/traces:batchWrite" body: "*" };
+  }
+
+  // Creates a new span.
+  rpc CreateSpan(Span) returns (Span) {
+    option (google.api.http) = { post: "/v2/{name=projects/*/traces/*}/spans" body: "*" };
+  }
+}
+
+// The request message for the `BatchWriteSpans` method.
+message BatchWriteSpansRequest {
+  // Required. The name of the project where the spans belong. The format is
+  // `projects/[PROJECT_ID]`.
+  string name = 1;
+
+  // A list of new spans. The span names must not match existing
+  // spans, or the results are undefined.
+  repeated Span spans = 2;
+}
diff --git a/trace/google/cloud/trace_v2/proto/trace.proto b/trace/google/cloud/trace_v2/proto/trace.proto
new file mode 100644
index 000000000000..aaa5ade0be56
--- /dev/null
+++ b/trace/google/cloud/trace_v2/proto/trace.proto
@@ -0,0 +1,336 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.devtools.cloudtrace.v2;
+
+import "google/api/annotations.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/wrappers.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.Trace.V2";
+option go_package = "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2;cloudtrace";
+option java_multiple_files = true;
+option java_outer_classname = "TraceProto";
+option java_package = "com.google.devtools.cloudtrace.v2";
+option php_namespace = "Google\\Cloud\\Trace\\V2";
+
+
+// A span represents a single operation within a trace. Spans can be
+// nested to form a trace tree. Often, a trace contains a root span
+// that describes the end-to-end latency, and one or more subspans for
+// its sub-operations. A trace can also contain multiple root spans,
+// or none at all. Spans do not need to be contiguous&mdash;there may be
+// gaps or overlaps between spans in a trace.
+message Span {
+  // A set of attributes, each in the format `[KEY]:[VALUE]`.
+  message Attributes {
+    // The set of attributes. Each attribute's key can be up to 128 bytes
+    // long. The value can be a string up to 256 bytes, an integer, or the
+    // Boolean values `true` and `false`. For example:
+    //
+    //     "/instance_id": "my-instance"
+    //     "/http/user_agent": ""
+    //     "/http/request_bytes": 300
+    //     "abc.com/myattribute": true
+    map<string, AttributeValue> attribute_map = 1;
+
+    // The number of attributes that were discarded. Attributes can be discarded
+    // because their keys are too long or because there are too many attributes.
+    // If this value is 0 then all attributes are valid.
+    int32 dropped_attributes_count = 2;
+  }
+
+  // A time-stamped annotation or message event in the Span.
+  message TimeEvent {
+    // Text annotation with a set of attributes.
+    message Annotation {
+      // A user-supplied message describing the event. The maximum length for
+      // the description is 256 bytes.
+      TruncatableString description = 1;
+
+      // A set of attributes on the annotation. You can have up to 4 attributes
+      // per Annotation.
+      Attributes attributes = 2;
+    }
+
+    // An event describing a message sent/received between Spans.
+    message MessageEvent {
+      // Indicates whether the message was sent or received.
+      enum Type {
+        // Unknown event type.
+        TYPE_UNSPECIFIED = 0;
+
+        // Indicates a sent message.
+        SENT = 1;
+
+        // Indicates a received message.
+        RECEIVED = 2;
+      }
+
+      // Type of MessageEvent. Indicates whether the message was sent or
+      // received.
+      Type type = 1;
+
+      // An identifier for the MessageEvent's message that can be used to match
+      // SENT and RECEIVED MessageEvents. It is recommended to be unique within
+      // a Span.
+      int64 id = 2;
+
+      // The number of uncompressed bytes sent or received.
+      int64 uncompressed_size_bytes = 3;
+
+      // The number of compressed bytes sent or received. If missing assumed to
+      // be the same size as uncompressed.
+      int64 compressed_size_bytes = 4;
+    }
+
+    // The timestamp indicating the time the event occurred.
+    google.protobuf.Timestamp time = 1;
+
+    // A `TimeEvent` can contain either an `Annotation` object or a
+    // `MessageEvent` object, but not both.
+    oneof value {
+      // Text annotation with a set of attributes.
+      Annotation annotation = 2;
+
+      // An event describing a message sent/received between Spans.
+      MessageEvent message_event = 3;
+    }
+  }
+
+  // A collection of `TimeEvent`s. A `TimeEvent` is a time-stamped annotation
+  // on the span, consisting of either user-supplied key:value pairs, or
+  // details of a message sent/received between Spans.
+  message TimeEvents {
+    // A collection of `TimeEvent`s.
+    repeated TimeEvent time_event = 1;
+
+    // The number of dropped annotations in all the included time events.
+    // If the value is 0, then no annotations were dropped.
+    int32 dropped_annotations_count = 2;
+
+    // The number of dropped message events in all the included time events.
+    // If the value is 0, then no message events were dropped.
+    int32 dropped_message_events_count = 3;
+  }
+
+  // A pointer from the current span to another span in the same trace or in a
+  // different trace. For example, this can be used in batching operations,
+  // where a single batch handler processes multiple requests from different
+  // traces or when the handler receives a request from a different project.
+  message Link {
+    // The relationship of the current span relative to the linked span: child,
+    // parent, or unspecified.
+    enum Type {
+      // The relationship of the two spans is unknown.
+      TYPE_UNSPECIFIED = 0;
+
+      // The linked span is a child of the current span.
+      CHILD_LINKED_SPAN = 1;
+
+      // The linked span is a parent of the current span.
+      PARENT_LINKED_SPAN = 2;
+    }
+
+    // The [TRACE_ID] for a trace within a project.
+    string trace_id = 1;
+
+    // The [SPAN_ID] for a span within a trace.
+    string span_id = 2;
+
+    // The relationship of the current span relative to the linked span.
+    Type type = 3;
+
+    // A set of attributes on the link. You have have up to  32 attributes per
+    // link.
+    Attributes attributes = 4;
+  }
+
+  // A collection of links, which are references from this span to a span
+  // in the same or different trace.
+  message Links {
+    // A collection of links.
+    repeated Link link = 1;
+
+    // The number of dropped links after the maximum size was enforced. If
+    // this value is 0, then no links were dropped.
+    int32 dropped_links_count = 2;
+  }
+
+  // The resource name of the span in the following format:
+  //
+  //     projects/[PROJECT_ID]/traces/[TRACE_ID]/spans/[SPAN_ID]
+  //
+  // [TRACE_ID] is a unique identifier for a trace within a project;
+  // it is a 32-character hexadecimal encoding of a 16-byte array.
+  //
+  // [SPAN_ID] is a unique identifier for a span within a trace; it
+  // is a 16-character hexadecimal encoding of an 8-byte array.
+  string name = 1;
+
+  // The [SPAN_ID] portion of the span's resource name.
+  string span_id = 2;
+
+  // The [SPAN_ID] of this span's parent span. If this is a root span,
+  // then this field must be empty.
+  string parent_span_id = 3;
+
+  // A description of the span's operation (up to 128 bytes).
+  // Stackdriver Trace displays the description in the
+  // {% dynamic print site_values.console_name %}.
+  // For example, the display name can be a qualified method name or a file name
+  // and a line number where the operation is called. A best practice is to use
+  // the same display name within an application and at the same call point.
+  // This makes it easier to correlate spans in different traces.
+  TruncatableString display_name = 4;
+
+  // The start time of the span. On the client side, this is the time kept by
+  // the local machine where the span execution starts. On the server side, this
+  // is the time when the server's application handler starts running.
+  google.protobuf.Timestamp start_time = 5;
+
+  // The end time of the span. On the client side, this is the time kept by
+  // the local machine where the span execution ends. On the server side, this
+  // is the time when the server application handler stops running.
+  google.protobuf.Timestamp end_time = 6;
+
+  // A set of attributes on the span. You can have up to 32 attributes per
+  // span.
+  Attributes attributes = 7;
+
+  // Stack trace captured at the start of the span.
+  StackTrace stack_trace = 8;
+
+  // A set of time events. You can have up to 32 annotations and 128 message
+  // events per span.
+  TimeEvents time_events = 9;
+
+  // Links associated with the span. You can have up to 128 links per Span.
+  Links links = 10;
+
+  // An optional final status for this span.
+  google.rpc.Status status = 11;
+
+  // (Optional) Set this parameter to indicate whether this span is in
+  // the same process as its parent. If you do not set this parameter,
+  // Stackdriver Trace is unable to take advantage of this helpful
+  // information.
+  google.protobuf.BoolValue same_process_as_parent_span = 12;
+
+  // An optional number of child spans that were generated while this span
+  // was active. If set, allows implementation to detect missing child spans.
+  google.protobuf.Int32Value child_span_count = 13;
+}
+
+// The allowed types for [VALUE] in a `[KEY]:[VALUE]` attribute.
+message AttributeValue {
+  // The type of the value.
+  oneof value {
+    // A string up to 256 bytes long.
+    TruncatableString string_value = 1;
+
+    // A 64-bit signed integer.
+    int64 int_value = 2;
+
+    // A Boolean value represented by `true` or `false`.
+    bool bool_value = 3;
+  }
+}
+
+// A call stack appearing in a trace.
+message StackTrace {
+  // Represents a single stack frame in a stack trace.
+  message StackFrame {
+    // The fully-qualified name that uniquely identifies the function or
+    // method that is active in this frame (up to 1024 bytes).
+    TruncatableString function_name = 1;
+
+    // An un-mangled function name, if `function_name` is
+    // [mangled](http://www.avabodh.com/cxxin/namemangling.html). The name can
+    // be fully-qualified (up to 1024 bytes).
+    TruncatableString original_function_name = 2;
+
+    // The name of the source file where the function call appears (up to 256
+    // bytes).
+    TruncatableString file_name = 3;
+
+    // The line number in `file_name` where the function call appears.
+    int64 line_number = 4;
+
+    // The column number where the function call appears, if available.
+    // This is important in JavaScript because of its anonymous functions.
+    int64 column_number = 5;
+
+    // The binary module from where the code was loaded.
+    Module load_module = 6;
+
+    // The version of the deployed source code (up to 128 bytes).
+    TruncatableString source_version = 7;
+  }
+
+  // A collection of stack frames, which can be truncated.
+  message StackFrames {
+    // Stack frames in this call stack.
+    repeated StackFrame frame = 1;
+
+    // The number of stack frames that were dropped because there
+    // were too many stack frames.
+    // If this value is 0, then no stack frames were dropped.
+    int32 dropped_frames_count = 2;
+  }
+
+  // Stack frames in this stack trace. A maximum of 128 frames are allowed.
+  StackFrames stack_frames = 1;
+
+  // The hash ID is used to conserve network bandwidth for duplicate
+  // stack traces within a single trace.
+  //
+  // Often multiple spans will have identical stack traces.
+  // The first occurrence of a stack trace should contain both the
+  // `stackFrame` content and a value in `stackTraceHashId`.
+  //
+  // Subsequent spans within the same request can refer
+  // to that stack trace by only setting `stackTraceHashId`.
+  int64 stack_trace_hash_id = 2;
+}
+
+// Binary module.
+message Module {
+  // For example: main binary, kernel modules, and dynamic libraries
+  // such as libc.so, sharedlib.so (up to 256 bytes).
+  TruncatableString module = 1;
+
+  // A unique identifier for the module, usually a hash of its
+  // contents (up to 128 bytes).
+  TruncatableString build_id = 2;
+}
+
+// Represents a string that might be shortened to a specified length.
+message TruncatableString {
+  // The shortened string. For example, if the original string is 500
+  // bytes long and the limit of the string is 128 bytes, then
+  // `value` contains the first 128 bytes of the 500-byte string.
+  //
+  // Truncation always happens on a UTF8 character boundary. If there
+  // are multi-byte characters in the string, then the length of the
+  // shortened string might be less than the size limit.
+  string value = 1;
+
+  // The number of bytes removed from the original string. If this
+  // value is 0, then the string was not shortened.
+  int32 truncated_byte_count = 2;
+}
diff --git a/trace/google/cloud/trace_v2/proto/trace_pb2.py b/trace/google/cloud/trace_v2/proto/trace_pb2.py
index 5298cb85dfe1..d41a75abbc0f 100644
--- a/trace/google/cloud/trace_v2/proto/trace_pb2.py
+++ b/trace/google/cloud/trace_v2/proto/trace_pb2.py
@@ -1907,3 +1907,4 @@
 DESCRIPTOR._options = None
 _SPAN_ATTRIBUTES_ATTRIBUTEMAPENTRY._options = None
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/trace/google/cloud/trace_v2/proto/tracing.proto b/trace/google/cloud/trace_v2/proto/tracing.proto
new file mode 100644
index 000000000000..fd4f3e027771
--- /dev/null
+++ b/trace/google/cloud/trace_v2/proto/tracing.proto
@@ -0,0 +1,59 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.devtools.cloudtrace.v2;
+
+import "google/api/annotations.proto";
+import "google/devtools/cloudtrace/v2/trace.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+
+option csharp_namespace = "Google.Cloud.Trace.V2";
+option go_package = "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2;cloudtrace";
+option java_multiple_files = true;
+option java_outer_classname = "TracingProto";
+option java_package = "com.google.devtools.cloudtrace.v2";
+option php_namespace = "Google\\Cloud\\Trace\\V2";
+
+
+// This file describes an API for collecting and viewing traces and spans
+// within a trace.  A Trace is a collection of spans corresponding to a single
+// operation or set of operations for an application. A span is an individual
+// timed event which forms a node of the trace tree. A single trace may
+// contain span(s) from multiple services.
+service TraceService {
+  // Sends new spans to new or existing traces. You cannot update
+  // existing spans.
+  rpc BatchWriteSpans(BatchWriteSpansRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = { post: "/v2/{name=projects/*}/traces:batchWrite" body: "*" };
+  }
+
+  // Creates a new span.
+  rpc CreateSpan(Span) returns (Span) {
+    option (google.api.http) = { post: "/v2/{name=projects/*/traces/*}/spans" body: "*" };
+  }
+}
+
+// The request message for the `BatchWriteSpans` method.
+message BatchWriteSpansRequest {
+  // Required. The name of the project where the spans belong. The format is
+  // `projects/[PROJECT_ID]`.
+  string name = 1;
+
+  // A list of new spans. The span names must not match existing
+  // spans, or the results are undefined.
+  repeated Span spans = 2;
+}
diff --git a/trace/google/cloud/trace_v2/proto/tracing_pb2.py b/trace/google/cloud/trace_v2/proto/tracing_pb2.py
index fa3989d8f725..834104261a81 100644
--- a/trace/google/cloud/trace_v2/proto/tracing_pb2.py
+++ b/trace/google/cloud/trace_v2/proto/tracing_pb2.py
@@ -167,3 +167,4 @@
 DESCRIPTOR.services_by_name["TraceService"] = _TRACESERVICE
 
 # @@protoc_insertion_point(module_scope)
+# -*- coding: utf-8 -*-
diff --git a/trace/synth.metadata b/trace/synth.metadata
index 90530f8baa69..ee7a18cb79ea 100644
--- a/trace/synth.metadata
+++ b/trace/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:30:30.556424Z",
+  "updateTime": "2019-01-24T17:41:35.237003Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/trace/synth.py b/trace/synth.py
index 573b5d6ffb21..bca840a4947a 100644
--- a/trace/synth.py
+++ b/trace/synth.py
@@ -29,6 +29,7 @@
         version,
         config_path=f"/google/devtools/cloudtrace" f"/artman_cloudtrace_{version}.yaml",
         artman_output_name=f"trace-{version}",
+        include_protos=True,
     )
 
     s.move(library / f"google/cloud/trace_{version}")
diff --git a/videointelligence/google/cloud/videointelligence_v1/proto/video_intelligence.proto b/videointelligence/google/cloud/videointelligence_v1/proto/video_intelligence.proto
new file mode 100644
index 000000000000..24bdb8eeb879
--- /dev/null
+++ b/videointelligence/google/cloud/videointelligence_v1/proto/video_intelligence.proto
@@ -0,0 +1,433 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.videointelligence.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.VideoIntelligence.V1P1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/cloud/videointelligence/v1p1beta1;videointelligence";
+option java_multiple_files = true;
+option java_outer_classname = "VideoIntelligenceServiceProto";
+option java_package = "com.google.cloud.videointelligence.v1p1beta1";
+option php_namespace = "Google\\Cloud\\VideoIntelligence\\V1p1beta1";
+
+
+// Service that implements Google Cloud Video Intelligence API.
+service VideoIntelligenceService {
+  // Performs asynchronous video annotation. Progress and results can be
+  // retrieved through the `google.longrunning.Operations` interface.
+  // `Operation.metadata` contains `AnnotateVideoProgress` (progress).
+  // `Operation.response` contains `AnnotateVideoResponse` (results).
+  rpc AnnotateVideo(AnnotateVideoRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/videos:annotate"
+      body: "*"
+    };
+  }
+}
+
+// Video annotation request.
+message AnnotateVideoRequest {
+  // Input video location. Currently, only
+  // [Google Cloud Storage](https://cloud.google.com/storage/) URIs are
+  // supported, which must be specified in the following format:
+  // `gs://bucket-id/object-id` (other URI formats return
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+  // [Request URIs](/storage/docs/reference-uris).
+  // A video URI may include wildcards in `object-id`, and thus identify
+  // multiple videos. Supported wildcards: '*' to match 0 or more characters;
+  // '?' to match 1 character. If unset, the input video should be embedded
+  // in the request as `input_content`. If set, `input_content` should be unset.
+  string input_uri = 1;
+
+  // The video data bytes.
+  // If unset, the input video(s) should be specified via `input_uri`.
+  // If set, `input_uri` should be unset.
+  bytes input_content = 6;
+
+  // Requested video annotation features.
+  repeated Feature features = 2;
+
+  // Additional video context and/or feature-specific parameters.
+  VideoContext video_context = 3;
+
+  // Optional location where the output (in JSON format) should be stored.
+  // Currently, only [Google Cloud Storage](https://cloud.google.com/storage/)
+  // URIs are supported, which must be specified in the following format:
+  // `gs://bucket-id/object-id` (other URI formats return
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+  // [Request URIs](/storage/docs/reference-uris).
+  string output_uri = 4;
+
+  // Optional cloud region where annotation should take place. Supported cloud
+  // regions: `us-east1`, `us-west1`, `europe-west1`, `asia-east1`. If no region
+  // is specified, a region will be determined based on video file location.
+  string location_id = 5;
+}
+
+// Video context and/or feature-specific parameters.
+message VideoContext {
+  // Video segments to annotate. The segments may overlap and are not required
+  // to be contiguous or span the whole video. If unspecified, each video is
+  // treated as a single segment.
+  repeated VideoSegment segments = 1;
+
+  // Config for LABEL_DETECTION.
+  LabelDetectionConfig label_detection_config = 2;
+
+  // Config for SHOT_CHANGE_DETECTION.
+  ShotChangeDetectionConfig shot_change_detection_config = 3;
+
+  // Config for EXPLICIT_CONTENT_DETECTION.
+  ExplicitContentDetectionConfig explicit_content_detection_config = 4;
+
+  // Config for SPEECH_TRANSCRIPTION.
+  SpeechTranscriptionConfig speech_transcription_config = 6;
+}
+
+// Config for LABEL_DETECTION.
+message LabelDetectionConfig {
+  // What labels should be detected with LABEL_DETECTION, in addition to
+  // video-level labels or segment-level labels.
+  // If unspecified, defaults to `SHOT_MODE`.
+  LabelDetectionMode label_detection_mode = 1;
+
+  // Whether the video has been shot from a stationary (i.e. non-moving) camera.
+  // When set to true, might improve detection accuracy for moving objects.
+  // Should be used with `SHOT_AND_FRAME_MODE` enabled.
+  bool stationary_camera = 2;
+
+  // Model to use for label detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 3;
+}
+
+// Config for SHOT_CHANGE_DETECTION.
+message ShotChangeDetectionConfig {
+  // Model to use for shot change detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 1;
+}
+
+// Config for EXPLICIT_CONTENT_DETECTION.
+message ExplicitContentDetectionConfig {
+  // Model to use for explicit content detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 1;
+}
+
+// Video segment.
+message VideoSegment {
+  // Time-offset, relative to the beginning of the video,
+  // corresponding to the start of the segment (inclusive).
+  google.protobuf.Duration start_time_offset = 1;
+
+  // Time-offset, relative to the beginning of the video,
+  // corresponding to the end of the segment (inclusive).
+  google.protobuf.Duration end_time_offset = 2;
+}
+
+// Video segment level annotation results for label detection.
+message LabelSegment {
+  // Video segment where a label was detected.
+  VideoSegment segment = 1;
+
+  // Confidence that the label is accurate. Range: [0, 1].
+  float confidence = 2;
+}
+
+// Video frame level annotation results for label detection.
+message LabelFrame {
+  // Time-offset, relative to the beginning of the video, corresponding to the
+  // video frame for this location.
+  google.protobuf.Duration time_offset = 1;
+
+  // Confidence that the label is accurate. Range: [0, 1].
+  float confidence = 2;
+}
+
+// Detected entity from video analysis.
+message Entity {
+  // Opaque entity ID. Some IDs may be available in
+  // [Google Knowledge Graph Search
+  // API](https://developers.google.com/knowledge-graph/).
+  string entity_id = 1;
+
+  // Textual description, e.g. `Fixed-gear bicycle`.
+  string description = 2;
+
+  // Language code for `description` in BCP-47 format.
+  string language_code = 3;
+}
+
+// Label annotation.
+message LabelAnnotation {
+  // Detected entity.
+  Entity entity = 1;
+
+  // Common categories for the detected entity.
+  // E.g. when the label is `Terrier` the category is likely `dog`. And in some
+  // cases there might be more than one categories e.g. `Terrier` could also be
+  // a `pet`.
+  repeated Entity category_entities = 2;
+
+  // All video segments where a label was detected.
+  repeated LabelSegment segments = 3;
+
+  // All video frames where a label was detected.
+  repeated LabelFrame frames = 4;
+}
+
+// Video frame level annotation results for explicit content.
+message ExplicitContentFrame {
+  // Time-offset, relative to the beginning of the video, corresponding to the
+  // video frame for this location.
+  google.protobuf.Duration time_offset = 1;
+
+  // Likelihood of the pornography content..
+  Likelihood pornography_likelihood = 2;
+}
+
+// Explicit content annotation (based on per-frame visual signals only).
+// If no explicit content has been detected in a frame, no annotations are
+// present for that frame.
+message ExplicitContentAnnotation {
+  // All video frames where explicit content was detected.
+  repeated ExplicitContentFrame frames = 1;
+}
+
+// Annotation results for a single video.
+message VideoAnnotationResults {
+  // Output only. Video file location in
+  // [Google Cloud Storage](https://cloud.google.com/storage/).
+  string input_uri = 1;
+
+  // Label annotations on video level or user specified segment level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation segment_label_annotations = 2;
+
+  // Label annotations on shot level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation shot_label_annotations = 3;
+
+  // Label annotations on frame level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation frame_label_annotations = 4;
+
+  // Shot annotations. Each shot is represented as a video segment.
+  repeated VideoSegment shot_annotations = 6;
+
+  // Explicit content annotation.
+  ExplicitContentAnnotation explicit_annotation = 7;
+
+  // Speech transcription.
+  repeated SpeechTranscription speech_transcriptions = 11;
+
+  // Output only. If set, indicates an error. Note that for a single
+  // `AnnotateVideoRequest` some videos may succeed and some may fail.
+  google.rpc.Status error = 9;
+}
+
+// Video annotation response. Included in the `response`
+// field of the `Operation` returned by the `GetOperation`
+// call of the `google::longrunning::Operations` service.
+message AnnotateVideoResponse {
+  // Annotation results for all videos specified in `AnnotateVideoRequest`.
+  repeated VideoAnnotationResults annotation_results = 1;
+}
+
+// Annotation progress for a single video.
+message VideoAnnotationProgress {
+  // Output only. Video file location in
+  // [Google Cloud Storage](https://cloud.google.com/storage/).
+  string input_uri = 1;
+
+  // Output only. Approximate percentage processed thus far. Guaranteed to be
+  // 100 when fully processed.
+  int32 progress_percent = 2;
+
+  // Output only. Time when the request was received.
+  google.protobuf.Timestamp start_time = 3;
+
+  // Output only. Time of the most recent update.
+  google.protobuf.Timestamp update_time = 4;
+}
+
+// Video annotation progress. Included in the `metadata`
+// field of the `Operation` returned by the `GetOperation`
+// call of the `google::longrunning::Operations` service.
+message AnnotateVideoProgress {
+  // Progress metadata for all videos specified in `AnnotateVideoRequest`.
+  repeated VideoAnnotationProgress annotation_progress = 1;
+}
+
+// Config for SPEECH_TRANSCRIPTION.
+message SpeechTranscriptionConfig {
+  // *Required* The language of the supplied audio as a
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag.
+  // Example: "en-US".
+  // See [Language Support](https://cloud.google.com/speech/docs/languages)
+  // for a list of the currently supported language codes.
+  string language_code = 1;
+
+  // *Optional* Maximum number of recognition hypotheses to be returned.
+  // Specifically, the maximum number of `SpeechRecognitionAlternative` messages
+  // within each `SpeechRecognitionResult`. The server may return fewer than
+  // `max_alternatives`. Valid values are `0`-`30`. A value of `0` or `1` will
+  // return a maximum of one. If omitted, will return a maximum of one.
+  int32 max_alternatives = 2;
+
+  // *Optional* If set to `true`, the server will attempt to filter out
+  // profanities, replacing all but the initial character in each filtered word
+  // with asterisks, e.g. "f***". If set to `false` or omitted, profanities
+  // won't be filtered out.
+  bool filter_profanity = 3;
+
+  // *Optional* A means to provide context to assist the speech recognition.
+  repeated SpeechContext speech_contexts = 4;
+
+  // *Optional* If 'true', adds punctuation to recognition result hypotheses.
+  // This feature is only available in select languages. Setting this for
+  // requests in other languages has no effect at all. The default 'false' value
+  // does not add punctuation to result hypotheses. NOTE: "This is currently
+  // offered as an experimental service, complimentary to all users. In the
+  // future this may be exclusively available as a premium feature."
+  bool enable_automatic_punctuation = 5;
+
+  // *Optional* For file formats, such as MXF or MKV, supporting multiple audio
+  // tracks, specify up to two tracks. Default: track 0.
+  repeated int32 audio_tracks = 6;
+}
+
+// Provides "hints" to the speech recognizer to favor specific words and phrases
+// in the results.
+message SpeechContext {
+  // *Optional* A list of strings containing words and phrases "hints" so that
+  // the speech recognition is more likely to recognize them. This can be used
+  // to improve the accuracy for specific words and phrases, for example, if
+  // specific commands are typically spoken by the user. This can also be used
+  // to add additional words to the vocabulary of the recognizer. See
+  // [usage limits](https://cloud.google.com/speech/limits#content).
+  repeated string phrases = 1;
+}
+
+// A speech recognition result corresponding to a portion of the audio.
+message SpeechTranscription {
+  // Output only. May contain one or more recognition hypotheses (up to the
+  // maximum specified in `max_alternatives`).
+  // These alternatives are ordered in terms of accuracy, with the top (first)
+  // alternative being the most probable, as ranked by the recognizer.
+  repeated SpeechRecognitionAlternative alternatives = 1;
+}
+
+// Alternative hypotheses (a.k.a. n-best list).
+message SpeechRecognitionAlternative {
+  // Output only. Transcript text representing the words that the user spoke.
+  string transcript = 1;
+
+  // Output only. The confidence estimate between 0.0 and 1.0. A higher number
+  // indicates an estimated greater likelihood that the recognized words are
+  // correct. This field is typically provided only for the top hypothesis, and
+  // only for `is_final=true` results. Clients should not rely on the
+  // `confidence` field as it is not guaranteed to be accurate or consistent.
+  // The default of 0.0 is a sentinel value indicating `confidence` was not set.
+  float confidence = 2;
+
+  // Output only. A list of word-specific information for each recognized word.
+  repeated WordInfo words = 3;
+}
+
+// Word-specific information for recognized words. Word information is only
+// included in the response when certain request parameters are set, such
+// as `enable_word_time_offsets`.
+message WordInfo {
+  // Output only. Time offset relative to the beginning of the audio, and
+  // corresponding to the start of the spoken word. This field is only set if
+  // `enable_word_time_offsets=true` and only in the top hypothesis. This is an
+  // experimental feature and the accuracy of the time offset can vary.
+  google.protobuf.Duration start_time = 1;
+
+  // Output only. Time offset relative to the beginning of the audio, and
+  // corresponding to the end of the spoken word. This field is only set if
+  // `enable_word_time_offsets=true` and only in the top hypothesis. This is an
+  // experimental feature and the accuracy of the time offset can vary.
+  google.protobuf.Duration end_time = 2;
+
+  // Output only. The word corresponding to this set of information.
+  string word = 3;
+}
+
+// Video annotation feature.
+enum Feature {
+  // Unspecified.
+  FEATURE_UNSPECIFIED = 0;
+
+  // Label detection. Detect objects, such as dog or flower.
+  LABEL_DETECTION = 1;
+
+  // Shot change detection.
+  SHOT_CHANGE_DETECTION = 2;
+
+  // Explicit content detection.
+  EXPLICIT_CONTENT_DETECTION = 3;
+
+  // Speech transcription.
+  SPEECH_TRANSCRIPTION = 6;
+}
+
+// Label detection mode.
+enum LabelDetectionMode {
+  // Unspecified.
+  LABEL_DETECTION_MODE_UNSPECIFIED = 0;
+
+  // Detect shot-level labels.
+  SHOT_MODE = 1;
+
+  // Detect frame-level labels.
+  FRAME_MODE = 2;
+
+  // Detect both shot-level and frame-level labels.
+  SHOT_AND_FRAME_MODE = 3;
+}
+
+// Bucketized representation of likelihood.
+enum Likelihood {
+  // Unspecified likelihood.
+  LIKELIHOOD_UNSPECIFIED = 0;
+
+  // Very unlikely.
+  VERY_UNLIKELY = 1;
+
+  // Unlikely.
+  UNLIKELY = 2;
+
+  // Possible.
+  POSSIBLE = 3;
+
+  // Likely.
+  LIKELY = 4;
+
+  // Very likely.
+  VERY_LIKELY = 5;
+}
diff --git a/videointelligence/google/cloud/videointelligence_v1beta1/proto/video_intelligence.proto b/videointelligence/google/cloud/videointelligence_v1beta1/proto/video_intelligence.proto
new file mode 100644
index 000000000000..24bdb8eeb879
--- /dev/null
+++ b/videointelligence/google/cloud/videointelligence_v1beta1/proto/video_intelligence.proto
@@ -0,0 +1,433 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.videointelligence.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.VideoIntelligence.V1P1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/cloud/videointelligence/v1p1beta1;videointelligence";
+option java_multiple_files = true;
+option java_outer_classname = "VideoIntelligenceServiceProto";
+option java_package = "com.google.cloud.videointelligence.v1p1beta1";
+option php_namespace = "Google\\Cloud\\VideoIntelligence\\V1p1beta1";
+
+
+// Service that implements Google Cloud Video Intelligence API.
+service VideoIntelligenceService {
+  // Performs asynchronous video annotation. Progress and results can be
+  // retrieved through the `google.longrunning.Operations` interface.
+  // `Operation.metadata` contains `AnnotateVideoProgress` (progress).
+  // `Operation.response` contains `AnnotateVideoResponse` (results).
+  rpc AnnotateVideo(AnnotateVideoRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/videos:annotate"
+      body: "*"
+    };
+  }
+}
+
+// Video annotation request.
+message AnnotateVideoRequest {
+  // Input video location. Currently, only
+  // [Google Cloud Storage](https://cloud.google.com/storage/) URIs are
+  // supported, which must be specified in the following format:
+  // `gs://bucket-id/object-id` (other URI formats return
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+  // [Request URIs](/storage/docs/reference-uris).
+  // A video URI may include wildcards in `object-id`, and thus identify
+  // multiple videos. Supported wildcards: '*' to match 0 or more characters;
+  // '?' to match 1 character. If unset, the input video should be embedded
+  // in the request as `input_content`. If set, `input_content` should be unset.
+  string input_uri = 1;
+
+  // The video data bytes.
+  // If unset, the input video(s) should be specified via `input_uri`.
+  // If set, `input_uri` should be unset.
+  bytes input_content = 6;
+
+  // Requested video annotation features.
+  repeated Feature features = 2;
+
+  // Additional video context and/or feature-specific parameters.
+  VideoContext video_context = 3;
+
+  // Optional location where the output (in JSON format) should be stored.
+  // Currently, only [Google Cloud Storage](https://cloud.google.com/storage/)
+  // URIs are supported, which must be specified in the following format:
+  // `gs://bucket-id/object-id` (other URI formats return
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+  // [Request URIs](/storage/docs/reference-uris).
+  string output_uri = 4;
+
+  // Optional cloud region where annotation should take place. Supported cloud
+  // regions: `us-east1`, `us-west1`, `europe-west1`, `asia-east1`. If no region
+  // is specified, a region will be determined based on video file location.
+  string location_id = 5;
+}
+
+// Video context and/or feature-specific parameters.
+message VideoContext {
+  // Video segments to annotate. The segments may overlap and are not required
+  // to be contiguous or span the whole video. If unspecified, each video is
+  // treated as a single segment.
+  repeated VideoSegment segments = 1;
+
+  // Config for LABEL_DETECTION.
+  LabelDetectionConfig label_detection_config = 2;
+
+  // Config for SHOT_CHANGE_DETECTION.
+  ShotChangeDetectionConfig shot_change_detection_config = 3;
+
+  // Config for EXPLICIT_CONTENT_DETECTION.
+  ExplicitContentDetectionConfig explicit_content_detection_config = 4;
+
+  // Config for SPEECH_TRANSCRIPTION.
+  SpeechTranscriptionConfig speech_transcription_config = 6;
+}
+
+// Config for LABEL_DETECTION.
+message LabelDetectionConfig {
+  // What labels should be detected with LABEL_DETECTION, in addition to
+  // video-level labels or segment-level labels.
+  // If unspecified, defaults to `SHOT_MODE`.
+  LabelDetectionMode label_detection_mode = 1;
+
+  // Whether the video has been shot from a stationary (i.e. non-moving) camera.
+  // When set to true, might improve detection accuracy for moving objects.
+  // Should be used with `SHOT_AND_FRAME_MODE` enabled.
+  bool stationary_camera = 2;
+
+  // Model to use for label detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 3;
+}
+
+// Config for SHOT_CHANGE_DETECTION.
+message ShotChangeDetectionConfig {
+  // Model to use for shot change detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 1;
+}
+
+// Config for EXPLICIT_CONTENT_DETECTION.
+message ExplicitContentDetectionConfig {
+  // Model to use for explicit content detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 1;
+}
+
+// Video segment.
+message VideoSegment {
+  // Time-offset, relative to the beginning of the video,
+  // corresponding to the start of the segment (inclusive).
+  google.protobuf.Duration start_time_offset = 1;
+
+  // Time-offset, relative to the beginning of the video,
+  // corresponding to the end of the segment (inclusive).
+  google.protobuf.Duration end_time_offset = 2;
+}
+
+// Video segment level annotation results for label detection.
+message LabelSegment {
+  // Video segment where a label was detected.
+  VideoSegment segment = 1;
+
+  // Confidence that the label is accurate. Range: [0, 1].
+  float confidence = 2;
+}
+
+// Video frame level annotation results for label detection.
+message LabelFrame {
+  // Time-offset, relative to the beginning of the video, corresponding to the
+  // video frame for this location.
+  google.protobuf.Duration time_offset = 1;
+
+  // Confidence that the label is accurate. Range: [0, 1].
+  float confidence = 2;
+}
+
+// Detected entity from video analysis.
+message Entity {
+  // Opaque entity ID. Some IDs may be available in
+  // [Google Knowledge Graph Search
+  // API](https://developers.google.com/knowledge-graph/).
+  string entity_id = 1;
+
+  // Textual description, e.g. `Fixed-gear bicycle`.
+  string description = 2;
+
+  // Language code for `description` in BCP-47 format.
+  string language_code = 3;
+}
+
+// Label annotation.
+message LabelAnnotation {
+  // Detected entity.
+  Entity entity = 1;
+
+  // Common categories for the detected entity.
+  // E.g. when the label is `Terrier` the category is likely `dog`. And in some
+  // cases there might be more than one categories e.g. `Terrier` could also be
+  // a `pet`.
+  repeated Entity category_entities = 2;
+
+  // All video segments where a label was detected.
+  repeated LabelSegment segments = 3;
+
+  // All video frames where a label was detected.
+  repeated LabelFrame frames = 4;
+}
+
+// Video frame level annotation results for explicit content.
+message ExplicitContentFrame {
+  // Time-offset, relative to the beginning of the video, corresponding to the
+  // video frame for this location.
+  google.protobuf.Duration time_offset = 1;
+
+  // Likelihood of the pornography content..
+  Likelihood pornography_likelihood = 2;
+}
+
+// Explicit content annotation (based on per-frame visual signals only).
+// If no explicit content has been detected in a frame, no annotations are
+// present for that frame.
+message ExplicitContentAnnotation {
+  // All video frames where explicit content was detected.
+  repeated ExplicitContentFrame frames = 1;
+}
+
+// Annotation results for a single video.
+message VideoAnnotationResults {
+  // Output only. Video file location in
+  // [Google Cloud Storage](https://cloud.google.com/storage/).
+  string input_uri = 1;
+
+  // Label annotations on video level or user specified segment level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation segment_label_annotations = 2;
+
+  // Label annotations on shot level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation shot_label_annotations = 3;
+
+  // Label annotations on frame level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation frame_label_annotations = 4;
+
+  // Shot annotations. Each shot is represented as a video segment.
+  repeated VideoSegment shot_annotations = 6;
+
+  // Explicit content annotation.
+  ExplicitContentAnnotation explicit_annotation = 7;
+
+  // Speech transcription.
+  repeated SpeechTranscription speech_transcriptions = 11;
+
+  // Output only. If set, indicates an error. Note that for a single
+  // `AnnotateVideoRequest` some videos may succeed and some may fail.
+  google.rpc.Status error = 9;
+}
+
+// Video annotation response. Included in the `response`
+// field of the `Operation` returned by the `GetOperation`
+// call of the `google::longrunning::Operations` service.
+message AnnotateVideoResponse {
+  // Annotation results for all videos specified in `AnnotateVideoRequest`.
+  repeated VideoAnnotationResults annotation_results = 1;
+}
+
+// Annotation progress for a single video.
+message VideoAnnotationProgress {
+  // Output only. Video file location in
+  // [Google Cloud Storage](https://cloud.google.com/storage/).
+  string input_uri = 1;
+
+  // Output only. Approximate percentage processed thus far. Guaranteed to be
+  // 100 when fully processed.
+  int32 progress_percent = 2;
+
+  // Output only. Time when the request was received.
+  google.protobuf.Timestamp start_time = 3;
+
+  // Output only. Time of the most recent update.
+  google.protobuf.Timestamp update_time = 4;
+}
+
+// Video annotation progress. Included in the `metadata`
+// field of the `Operation` returned by the `GetOperation`
+// call of the `google::longrunning::Operations` service.
+message AnnotateVideoProgress {
+  // Progress metadata for all videos specified in `AnnotateVideoRequest`.
+  repeated VideoAnnotationProgress annotation_progress = 1;
+}
+
+// Config for SPEECH_TRANSCRIPTION.
+message SpeechTranscriptionConfig {
+  // *Required* The language of the supplied audio as a
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag.
+  // Example: "en-US".
+  // See [Language Support](https://cloud.google.com/speech/docs/languages)
+  // for a list of the currently supported language codes.
+  string language_code = 1;
+
+  // *Optional* Maximum number of recognition hypotheses to be returned.
+  // Specifically, the maximum number of `SpeechRecognitionAlternative` messages
+  // within each `SpeechRecognitionResult`. The server may return fewer than
+  // `max_alternatives`. Valid values are `0`-`30`. A value of `0` or `1` will
+  // return a maximum of one. If omitted, will return a maximum of one.
+  int32 max_alternatives = 2;
+
+  // *Optional* If set to `true`, the server will attempt to filter out
+  // profanities, replacing all but the initial character in each filtered word
+  // with asterisks, e.g. "f***". If set to `false` or omitted, profanities
+  // won't be filtered out.
+  bool filter_profanity = 3;
+
+  // *Optional* A means to provide context to assist the speech recognition.
+  repeated SpeechContext speech_contexts = 4;
+
+  // *Optional* If 'true', adds punctuation to recognition result hypotheses.
+  // This feature is only available in select languages. Setting this for
+  // requests in other languages has no effect at all. The default 'false' value
+  // does not add punctuation to result hypotheses. NOTE: "This is currently
+  // offered as an experimental service, complimentary to all users. In the
+  // future this may be exclusively available as a premium feature."
+  bool enable_automatic_punctuation = 5;
+
+  // *Optional* For file formats, such as MXF or MKV, supporting multiple audio
+  // tracks, specify up to two tracks. Default: track 0.
+  repeated int32 audio_tracks = 6;
+}
+
+// Provides "hints" to the speech recognizer to favor specific words and phrases
+// in the results.
+message SpeechContext {
+  // *Optional* A list of strings containing words and phrases "hints" so that
+  // the speech recognition is more likely to recognize them. This can be used
+  // to improve the accuracy for specific words and phrases, for example, if
+  // specific commands are typically spoken by the user. This can also be used
+  // to add additional words to the vocabulary of the recognizer. See
+  // [usage limits](https://cloud.google.com/speech/limits#content).
+  repeated string phrases = 1;
+}
+
+// A speech recognition result corresponding to a portion of the audio.
+message SpeechTranscription {
+  // Output only. May contain one or more recognition hypotheses (up to the
+  // maximum specified in `max_alternatives`).
+  // These alternatives are ordered in terms of accuracy, with the top (first)
+  // alternative being the most probable, as ranked by the recognizer.
+  repeated SpeechRecognitionAlternative alternatives = 1;
+}
+
+// Alternative hypotheses (a.k.a. n-best list).
+message SpeechRecognitionAlternative {
+  // Output only. Transcript text representing the words that the user spoke.
+  string transcript = 1;
+
+  // Output only. The confidence estimate between 0.0 and 1.0. A higher number
+  // indicates an estimated greater likelihood that the recognized words are
+  // correct. This field is typically provided only for the top hypothesis, and
+  // only for `is_final=true` results. Clients should not rely on the
+  // `confidence` field as it is not guaranteed to be accurate or consistent.
+  // The default of 0.0 is a sentinel value indicating `confidence` was not set.
+  float confidence = 2;
+
+  // Output only. A list of word-specific information for each recognized word.
+  repeated WordInfo words = 3;
+}
+
+// Word-specific information for recognized words. Word information is only
+// included in the response when certain request parameters are set, such
+// as `enable_word_time_offsets`.
+message WordInfo {
+  // Output only. Time offset relative to the beginning of the audio, and
+  // corresponding to the start of the spoken word. This field is only set if
+  // `enable_word_time_offsets=true` and only in the top hypothesis. This is an
+  // experimental feature and the accuracy of the time offset can vary.
+  google.protobuf.Duration start_time = 1;
+
+  // Output only. Time offset relative to the beginning of the audio, and
+  // corresponding to the end of the spoken word. This field is only set if
+  // `enable_word_time_offsets=true` and only in the top hypothesis. This is an
+  // experimental feature and the accuracy of the time offset can vary.
+  google.protobuf.Duration end_time = 2;
+
+  // Output only. The word corresponding to this set of information.
+  string word = 3;
+}
+
+// Video annotation feature.
+enum Feature {
+  // Unspecified.
+  FEATURE_UNSPECIFIED = 0;
+
+  // Label detection. Detect objects, such as dog or flower.
+  LABEL_DETECTION = 1;
+
+  // Shot change detection.
+  SHOT_CHANGE_DETECTION = 2;
+
+  // Explicit content detection.
+  EXPLICIT_CONTENT_DETECTION = 3;
+
+  // Speech transcription.
+  SPEECH_TRANSCRIPTION = 6;
+}
+
+// Label detection mode.
+enum LabelDetectionMode {
+  // Unspecified.
+  LABEL_DETECTION_MODE_UNSPECIFIED = 0;
+
+  // Detect shot-level labels.
+  SHOT_MODE = 1;
+
+  // Detect frame-level labels.
+  FRAME_MODE = 2;
+
+  // Detect both shot-level and frame-level labels.
+  SHOT_AND_FRAME_MODE = 3;
+}
+
+// Bucketized representation of likelihood.
+enum Likelihood {
+  // Unspecified likelihood.
+  LIKELIHOOD_UNSPECIFIED = 0;
+
+  // Very unlikely.
+  VERY_UNLIKELY = 1;
+
+  // Unlikely.
+  UNLIKELY = 2;
+
+  // Possible.
+  POSSIBLE = 3;
+
+  // Likely.
+  LIKELY = 4;
+
+  // Very likely.
+  VERY_LIKELY = 5;
+}
diff --git a/videointelligence/google/cloud/videointelligence_v1beta2/proto/video_intelligence.proto b/videointelligence/google/cloud/videointelligence_v1beta2/proto/video_intelligence.proto
new file mode 100644
index 000000000000..24bdb8eeb879
--- /dev/null
+++ b/videointelligence/google/cloud/videointelligence_v1beta2/proto/video_intelligence.proto
@@ -0,0 +1,433 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.videointelligence.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.VideoIntelligence.V1P1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/cloud/videointelligence/v1p1beta1;videointelligence";
+option java_multiple_files = true;
+option java_outer_classname = "VideoIntelligenceServiceProto";
+option java_package = "com.google.cloud.videointelligence.v1p1beta1";
+option php_namespace = "Google\\Cloud\\VideoIntelligence\\V1p1beta1";
+
+
+// Service that implements Google Cloud Video Intelligence API.
+service VideoIntelligenceService {
+  // Performs asynchronous video annotation. Progress and results can be
+  // retrieved through the `google.longrunning.Operations` interface.
+  // `Operation.metadata` contains `AnnotateVideoProgress` (progress).
+  // `Operation.response` contains `AnnotateVideoResponse` (results).
+  rpc AnnotateVideo(AnnotateVideoRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/videos:annotate"
+      body: "*"
+    };
+  }
+}
+
+// Video annotation request.
+message AnnotateVideoRequest {
+  // Input video location. Currently, only
+  // [Google Cloud Storage](https://cloud.google.com/storage/) URIs are
+  // supported, which must be specified in the following format:
+  // `gs://bucket-id/object-id` (other URI formats return
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+  // [Request URIs](/storage/docs/reference-uris).
+  // A video URI may include wildcards in `object-id`, and thus identify
+  // multiple videos. Supported wildcards: '*' to match 0 or more characters;
+  // '?' to match 1 character. If unset, the input video should be embedded
+  // in the request as `input_content`. If set, `input_content` should be unset.
+  string input_uri = 1;
+
+  // The video data bytes.
+  // If unset, the input video(s) should be specified via `input_uri`.
+  // If set, `input_uri` should be unset.
+  bytes input_content = 6;
+
+  // Requested video annotation features.
+  repeated Feature features = 2;
+
+  // Additional video context and/or feature-specific parameters.
+  VideoContext video_context = 3;
+
+  // Optional location where the output (in JSON format) should be stored.
+  // Currently, only [Google Cloud Storage](https://cloud.google.com/storage/)
+  // URIs are supported, which must be specified in the following format:
+  // `gs://bucket-id/object-id` (other URI formats return
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+  // [Request URIs](/storage/docs/reference-uris).
+  string output_uri = 4;
+
+  // Optional cloud region where annotation should take place. Supported cloud
+  // regions: `us-east1`, `us-west1`, `europe-west1`, `asia-east1`. If no region
+  // is specified, a region will be determined based on video file location.
+  string location_id = 5;
+}
+
+// Video context and/or feature-specific parameters.
+message VideoContext {
+  // Video segments to annotate. The segments may overlap and are not required
+  // to be contiguous or span the whole video. If unspecified, each video is
+  // treated as a single segment.
+  repeated VideoSegment segments = 1;
+
+  // Config for LABEL_DETECTION.
+  LabelDetectionConfig label_detection_config = 2;
+
+  // Config for SHOT_CHANGE_DETECTION.
+  ShotChangeDetectionConfig shot_change_detection_config = 3;
+
+  // Config for EXPLICIT_CONTENT_DETECTION.
+  ExplicitContentDetectionConfig explicit_content_detection_config = 4;
+
+  // Config for SPEECH_TRANSCRIPTION.
+  SpeechTranscriptionConfig speech_transcription_config = 6;
+}
+
+// Config for LABEL_DETECTION.
+message LabelDetectionConfig {
+  // What labels should be detected with LABEL_DETECTION, in addition to
+  // video-level labels or segment-level labels.
+  // If unspecified, defaults to `SHOT_MODE`.
+  LabelDetectionMode label_detection_mode = 1;
+
+  // Whether the video has been shot from a stationary (i.e. non-moving) camera.
+  // When set to true, might improve detection accuracy for moving objects.
+  // Should be used with `SHOT_AND_FRAME_MODE` enabled.
+  bool stationary_camera = 2;
+
+  // Model to use for label detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 3;
+}
+
+// Config for SHOT_CHANGE_DETECTION.
+message ShotChangeDetectionConfig {
+  // Model to use for shot change detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 1;
+}
+
+// Config for EXPLICIT_CONTENT_DETECTION.
+message ExplicitContentDetectionConfig {
+  // Model to use for explicit content detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 1;
+}
+
+// Video segment.
+message VideoSegment {
+  // Time-offset, relative to the beginning of the video,
+  // corresponding to the start of the segment (inclusive).
+  google.protobuf.Duration start_time_offset = 1;
+
+  // Time-offset, relative to the beginning of the video,
+  // corresponding to the end of the segment (inclusive).
+  google.protobuf.Duration end_time_offset = 2;
+}
+
+// Video segment level annotation results for label detection.
+message LabelSegment {
+  // Video segment where a label was detected.
+  VideoSegment segment = 1;
+
+  // Confidence that the label is accurate. Range: [0, 1].
+  float confidence = 2;
+}
+
+// Video frame level annotation results for label detection.
+message LabelFrame {
+  // Time-offset, relative to the beginning of the video, corresponding to the
+  // video frame for this location.
+  google.protobuf.Duration time_offset = 1;
+
+  // Confidence that the label is accurate. Range: [0, 1].
+  float confidence = 2;
+}
+
+// Detected entity from video analysis.
+message Entity {
+  // Opaque entity ID. Some IDs may be available in
+  // [Google Knowledge Graph Search
+  // API](https://developers.google.com/knowledge-graph/).
+  string entity_id = 1;
+
+  // Textual description, e.g. `Fixed-gear bicycle`.
+  string description = 2;
+
+  // Language code for `description` in BCP-47 format.
+  string language_code = 3;
+}
+
+// Label annotation.
+message LabelAnnotation {
+  // Detected entity.
+  Entity entity = 1;
+
+  // Common categories for the detected entity.
+  // E.g. when the label is `Terrier` the category is likely `dog`. And in some
+  // cases there might be more than one categories e.g. `Terrier` could also be
+  // a `pet`.
+  repeated Entity category_entities = 2;
+
+  // All video segments where a label was detected.
+  repeated LabelSegment segments = 3;
+
+  // All video frames where a label was detected.
+  repeated LabelFrame frames = 4;
+}
+
+// Video frame level annotation results for explicit content.
+message ExplicitContentFrame {
+  // Time-offset, relative to the beginning of the video, corresponding to the
+  // video frame for this location.
+  google.protobuf.Duration time_offset = 1;
+
+  // Likelihood of the pornography content..
+  Likelihood pornography_likelihood = 2;
+}
+
+// Explicit content annotation (based on per-frame visual signals only).
+// If no explicit content has been detected in a frame, no annotations are
+// present for that frame.
+message ExplicitContentAnnotation {
+  // All video frames where explicit content was detected.
+  repeated ExplicitContentFrame frames = 1;
+}
+
+// Annotation results for a single video.
+message VideoAnnotationResults {
+  // Output only. Video file location in
+  // [Google Cloud Storage](https://cloud.google.com/storage/).
+  string input_uri = 1;
+
+  // Label annotations on video level or user specified segment level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation segment_label_annotations = 2;
+
+  // Label annotations on shot level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation shot_label_annotations = 3;
+
+  // Label annotations on frame level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation frame_label_annotations = 4;
+
+  // Shot annotations. Each shot is represented as a video segment.
+  repeated VideoSegment shot_annotations = 6;
+
+  // Explicit content annotation.
+  ExplicitContentAnnotation explicit_annotation = 7;
+
+  // Speech transcription.
+  repeated SpeechTranscription speech_transcriptions = 11;
+
+  // Output only. If set, indicates an error. Note that for a single
+  // `AnnotateVideoRequest` some videos may succeed and some may fail.
+  google.rpc.Status error = 9;
+}
+
+// Video annotation response. Included in the `response`
+// field of the `Operation` returned by the `GetOperation`
+// call of the `google::longrunning::Operations` service.
+message AnnotateVideoResponse {
+  // Annotation results for all videos specified in `AnnotateVideoRequest`.
+  repeated VideoAnnotationResults annotation_results = 1;
+}
+
+// Annotation progress for a single video.
+message VideoAnnotationProgress {
+  // Output only. Video file location in
+  // [Google Cloud Storage](https://cloud.google.com/storage/).
+  string input_uri = 1;
+
+  // Output only. Approximate percentage processed thus far. Guaranteed to be
+  // 100 when fully processed.
+  int32 progress_percent = 2;
+
+  // Output only. Time when the request was received.
+  google.protobuf.Timestamp start_time = 3;
+
+  // Output only. Time of the most recent update.
+  google.protobuf.Timestamp update_time = 4;
+}
+
+// Video annotation progress. Included in the `metadata`
+// field of the `Operation` returned by the `GetOperation`
+// call of the `google::longrunning::Operations` service.
+message AnnotateVideoProgress {
+  // Progress metadata for all videos specified in `AnnotateVideoRequest`.
+  repeated VideoAnnotationProgress annotation_progress = 1;
+}
+
+// Config for SPEECH_TRANSCRIPTION.
+message SpeechTranscriptionConfig {
+  // *Required* The language of the supplied audio as a
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag.
+  // Example: "en-US".
+  // See [Language Support](https://cloud.google.com/speech/docs/languages)
+  // for a list of the currently supported language codes.
+  string language_code = 1;
+
+  // *Optional* Maximum number of recognition hypotheses to be returned.
+  // Specifically, the maximum number of `SpeechRecognitionAlternative` messages
+  // within each `SpeechRecognitionResult`. The server may return fewer than
+  // `max_alternatives`. Valid values are `0`-`30`. A value of `0` or `1` will
+  // return a maximum of one. If omitted, will return a maximum of one.
+  int32 max_alternatives = 2;
+
+  // *Optional* If set to `true`, the server will attempt to filter out
+  // profanities, replacing all but the initial character in each filtered word
+  // with asterisks, e.g. "f***". If set to `false` or omitted, profanities
+  // won't be filtered out.
+  bool filter_profanity = 3;
+
+  // *Optional* A means to provide context to assist the speech recognition.
+  repeated SpeechContext speech_contexts = 4;
+
+  // *Optional* If 'true', adds punctuation to recognition result hypotheses.
+  // This feature is only available in select languages. Setting this for
+  // requests in other languages has no effect at all. The default 'false' value
+  // does not add punctuation to result hypotheses. NOTE: "This is currently
+  // offered as an experimental service, complimentary to all users. In the
+  // future this may be exclusively available as a premium feature."
+  bool enable_automatic_punctuation = 5;
+
+  // *Optional* For file formats, such as MXF or MKV, supporting multiple audio
+  // tracks, specify up to two tracks. Default: track 0.
+  repeated int32 audio_tracks = 6;
+}
+
+// Provides "hints" to the speech recognizer to favor specific words and phrases
+// in the results.
+message SpeechContext {
+  // *Optional* A list of strings containing words and phrases "hints" so that
+  // the speech recognition is more likely to recognize them. This can be used
+  // to improve the accuracy for specific words and phrases, for example, if
+  // specific commands are typically spoken by the user. This can also be used
+  // to add additional words to the vocabulary of the recognizer. See
+  // [usage limits](https://cloud.google.com/speech/limits#content).
+  repeated string phrases = 1;
+}
+
+// A speech recognition result corresponding to a portion of the audio.
+message SpeechTranscription {
+  // Output only. May contain one or more recognition hypotheses (up to the
+  // maximum specified in `max_alternatives`).
+  // These alternatives are ordered in terms of accuracy, with the top (first)
+  // alternative being the most probable, as ranked by the recognizer.
+  repeated SpeechRecognitionAlternative alternatives = 1;
+}
+
+// Alternative hypotheses (a.k.a. n-best list).
+message SpeechRecognitionAlternative {
+  // Output only. Transcript text representing the words that the user spoke.
+  string transcript = 1;
+
+  // Output only. The confidence estimate between 0.0 and 1.0. A higher number
+  // indicates an estimated greater likelihood that the recognized words are
+  // correct. This field is typically provided only for the top hypothesis, and
+  // only for `is_final=true` results. Clients should not rely on the
+  // `confidence` field as it is not guaranteed to be accurate or consistent.
+  // The default of 0.0 is a sentinel value indicating `confidence` was not set.
+  float confidence = 2;
+
+  // Output only. A list of word-specific information for each recognized word.
+  repeated WordInfo words = 3;
+}
+
+// Word-specific information for recognized words. Word information is only
+// included in the response when certain request parameters are set, such
+// as `enable_word_time_offsets`.
+message WordInfo {
+  // Output only. Time offset relative to the beginning of the audio, and
+  // corresponding to the start of the spoken word. This field is only set if
+  // `enable_word_time_offsets=true` and only in the top hypothesis. This is an
+  // experimental feature and the accuracy of the time offset can vary.
+  google.protobuf.Duration start_time = 1;
+
+  // Output only. Time offset relative to the beginning of the audio, and
+  // corresponding to the end of the spoken word. This field is only set if
+  // `enable_word_time_offsets=true` and only in the top hypothesis. This is an
+  // experimental feature and the accuracy of the time offset can vary.
+  google.protobuf.Duration end_time = 2;
+
+  // Output only. The word corresponding to this set of information.
+  string word = 3;
+}
+
+// Video annotation feature.
+enum Feature {
+  // Unspecified.
+  FEATURE_UNSPECIFIED = 0;
+
+  // Label detection. Detect objects, such as dog or flower.
+  LABEL_DETECTION = 1;
+
+  // Shot change detection.
+  SHOT_CHANGE_DETECTION = 2;
+
+  // Explicit content detection.
+  EXPLICIT_CONTENT_DETECTION = 3;
+
+  // Speech transcription.
+  SPEECH_TRANSCRIPTION = 6;
+}
+
+// Label detection mode.
+enum LabelDetectionMode {
+  // Unspecified.
+  LABEL_DETECTION_MODE_UNSPECIFIED = 0;
+
+  // Detect shot-level labels.
+  SHOT_MODE = 1;
+
+  // Detect frame-level labels.
+  FRAME_MODE = 2;
+
+  // Detect both shot-level and frame-level labels.
+  SHOT_AND_FRAME_MODE = 3;
+}
+
+// Bucketized representation of likelihood.
+enum Likelihood {
+  // Unspecified likelihood.
+  LIKELIHOOD_UNSPECIFIED = 0;
+
+  // Very unlikely.
+  VERY_UNLIKELY = 1;
+
+  // Unlikely.
+  UNLIKELY = 2;
+
+  // Possible.
+  POSSIBLE = 3;
+
+  // Likely.
+  LIKELY = 4;
+
+  // Very likely.
+  VERY_LIKELY = 5;
+}
diff --git a/videointelligence/google/cloud/videointelligence_v1p1beta1/proto/video_intelligence.proto b/videointelligence/google/cloud/videointelligence_v1p1beta1/proto/video_intelligence.proto
new file mode 100644
index 000000000000..24bdb8eeb879
--- /dev/null
+++ b/videointelligence/google/cloud/videointelligence_v1p1beta1/proto/video_intelligence.proto
@@ -0,0 +1,433 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.videointelligence.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.VideoIntelligence.V1P1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/cloud/videointelligence/v1p1beta1;videointelligence";
+option java_multiple_files = true;
+option java_outer_classname = "VideoIntelligenceServiceProto";
+option java_package = "com.google.cloud.videointelligence.v1p1beta1";
+option php_namespace = "Google\\Cloud\\VideoIntelligence\\V1p1beta1";
+
+
+// Service that implements Google Cloud Video Intelligence API.
+service VideoIntelligenceService {
+  // Performs asynchronous video annotation. Progress and results can be
+  // retrieved through the `google.longrunning.Operations` interface.
+  // `Operation.metadata` contains `AnnotateVideoProgress` (progress).
+  // `Operation.response` contains `AnnotateVideoResponse` (results).
+  rpc AnnotateVideo(AnnotateVideoRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/videos:annotate"
+      body: "*"
+    };
+  }
+}
+
+// Video annotation request.
+message AnnotateVideoRequest {
+  // Input video location. Currently, only
+  // [Google Cloud Storage](https://cloud.google.com/storage/) URIs are
+  // supported, which must be specified in the following format:
+  // `gs://bucket-id/object-id` (other URI formats return
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+  // [Request URIs](/storage/docs/reference-uris).
+  // A video URI may include wildcards in `object-id`, and thus identify
+  // multiple videos. Supported wildcards: '*' to match 0 or more characters;
+  // '?' to match 1 character. If unset, the input video should be embedded
+  // in the request as `input_content`. If set, `input_content` should be unset.
+  string input_uri = 1;
+
+  // The video data bytes.
+  // If unset, the input video(s) should be specified via `input_uri`.
+  // If set, `input_uri` should be unset.
+  bytes input_content = 6;
+
+  // Requested video annotation features.
+  repeated Feature features = 2;
+
+  // Additional video context and/or feature-specific parameters.
+  VideoContext video_context = 3;
+
+  // Optional location where the output (in JSON format) should be stored.
+  // Currently, only [Google Cloud Storage](https://cloud.google.com/storage/)
+  // URIs are supported, which must be specified in the following format:
+  // `gs://bucket-id/object-id` (other URI formats return
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+  // [Request URIs](/storage/docs/reference-uris).
+  string output_uri = 4;
+
+  // Optional cloud region where annotation should take place. Supported cloud
+  // regions: `us-east1`, `us-west1`, `europe-west1`, `asia-east1`. If no region
+  // is specified, a region will be determined based on video file location.
+  string location_id = 5;
+}
+
+// Video context and/or feature-specific parameters.
+message VideoContext {
+  // Video segments to annotate. The segments may overlap and are not required
+  // to be contiguous or span the whole video. If unspecified, each video is
+  // treated as a single segment.
+  repeated VideoSegment segments = 1;
+
+  // Config for LABEL_DETECTION.
+  LabelDetectionConfig label_detection_config = 2;
+
+  // Config for SHOT_CHANGE_DETECTION.
+  ShotChangeDetectionConfig shot_change_detection_config = 3;
+
+  // Config for EXPLICIT_CONTENT_DETECTION.
+  ExplicitContentDetectionConfig explicit_content_detection_config = 4;
+
+  // Config for SPEECH_TRANSCRIPTION.
+  SpeechTranscriptionConfig speech_transcription_config = 6;
+}
+
+// Config for LABEL_DETECTION.
+message LabelDetectionConfig {
+  // What labels should be detected with LABEL_DETECTION, in addition to
+  // video-level labels or segment-level labels.
+  // If unspecified, defaults to `SHOT_MODE`.
+  LabelDetectionMode label_detection_mode = 1;
+
+  // Whether the video has been shot from a stationary (i.e. non-moving) camera.
+  // When set to true, might improve detection accuracy for moving objects.
+  // Should be used with `SHOT_AND_FRAME_MODE` enabled.
+  bool stationary_camera = 2;
+
+  // Model to use for label detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 3;
+}
+
+// Config for SHOT_CHANGE_DETECTION.
+message ShotChangeDetectionConfig {
+  // Model to use for shot change detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 1;
+}
+
+// Config for EXPLICIT_CONTENT_DETECTION.
+message ExplicitContentDetectionConfig {
+  // Model to use for explicit content detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 1;
+}
+
+// Video segment.
+message VideoSegment {
+  // Time-offset, relative to the beginning of the video,
+  // corresponding to the start of the segment (inclusive).
+  google.protobuf.Duration start_time_offset = 1;
+
+  // Time-offset, relative to the beginning of the video,
+  // corresponding to the end of the segment (inclusive).
+  google.protobuf.Duration end_time_offset = 2;
+}
+
+// Video segment level annotation results for label detection.
+message LabelSegment {
+  // Video segment where a label was detected.
+  VideoSegment segment = 1;
+
+  // Confidence that the label is accurate. Range: [0, 1].
+  float confidence = 2;
+}
+
+// Video frame level annotation results for label detection.
+message LabelFrame {
+  // Time-offset, relative to the beginning of the video, corresponding to the
+  // video frame for this location.
+  google.protobuf.Duration time_offset = 1;
+
+  // Confidence that the label is accurate. Range: [0, 1].
+  float confidence = 2;
+}
+
+// Detected entity from video analysis.
+message Entity {
+  // Opaque entity ID. Some IDs may be available in
+  // [Google Knowledge Graph Search
+  // API](https://developers.google.com/knowledge-graph/).
+  string entity_id = 1;
+
+  // Textual description, e.g. `Fixed-gear bicycle`.
+  string description = 2;
+
+  // Language code for `description` in BCP-47 format.
+  string language_code = 3;
+}
+
+// Label annotation.
+message LabelAnnotation {
+  // Detected entity.
+  Entity entity = 1;
+
+  // Common categories for the detected entity.
+  // E.g. when the label is `Terrier` the category is likely `dog`. And in some
+  // cases there might be more than one categories e.g. `Terrier` could also be
+  // a `pet`.
+  repeated Entity category_entities = 2;
+
+  // All video segments where a label was detected.
+  repeated LabelSegment segments = 3;
+
+  // All video frames where a label was detected.
+  repeated LabelFrame frames = 4;
+}
+
+// Video frame level annotation results for explicit content.
+message ExplicitContentFrame {
+  // Time-offset, relative to the beginning of the video, corresponding to the
+  // video frame for this location.
+  google.protobuf.Duration time_offset = 1;
+
+  // Likelihood of the pornography content..
+  Likelihood pornography_likelihood = 2;
+}
+
+// Explicit content annotation (based on per-frame visual signals only).
+// If no explicit content has been detected in a frame, no annotations are
+// present for that frame.
+message ExplicitContentAnnotation {
+  // All video frames where explicit content was detected.
+  repeated ExplicitContentFrame frames = 1;
+}
+
+// Annotation results for a single video.
+message VideoAnnotationResults {
+  // Output only. Video file location in
+  // [Google Cloud Storage](https://cloud.google.com/storage/).
+  string input_uri = 1;
+
+  // Label annotations on video level or user specified segment level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation segment_label_annotations = 2;
+
+  // Label annotations on shot level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation shot_label_annotations = 3;
+
+  // Label annotations on frame level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation frame_label_annotations = 4;
+
+  // Shot annotations. Each shot is represented as a video segment.
+  repeated VideoSegment shot_annotations = 6;
+
+  // Explicit content annotation.
+  ExplicitContentAnnotation explicit_annotation = 7;
+
+  // Speech transcription.
+  repeated SpeechTranscription speech_transcriptions = 11;
+
+  // Output only. If set, indicates an error. Note that for a single
+  // `AnnotateVideoRequest` some videos may succeed and some may fail.
+  google.rpc.Status error = 9;
+}
+
+// Video annotation response. Included in the `response`
+// field of the `Operation` returned by the `GetOperation`
+// call of the `google::longrunning::Operations` service.
+message AnnotateVideoResponse {
+  // Annotation results for all videos specified in `AnnotateVideoRequest`.
+  repeated VideoAnnotationResults annotation_results = 1;
+}
+
+// Annotation progress for a single video.
+message VideoAnnotationProgress {
+  // Output only. Video file location in
+  // [Google Cloud Storage](https://cloud.google.com/storage/).
+  string input_uri = 1;
+
+  // Output only. Approximate percentage processed thus far. Guaranteed to be
+  // 100 when fully processed.
+  int32 progress_percent = 2;
+
+  // Output only. Time when the request was received.
+  google.protobuf.Timestamp start_time = 3;
+
+  // Output only. Time of the most recent update.
+  google.protobuf.Timestamp update_time = 4;
+}
+
+// Video annotation progress. Included in the `metadata`
+// field of the `Operation` returned by the `GetOperation`
+// call of the `google::longrunning::Operations` service.
+message AnnotateVideoProgress {
+  // Progress metadata for all videos specified in `AnnotateVideoRequest`.
+  repeated VideoAnnotationProgress annotation_progress = 1;
+}
+
+// Config for SPEECH_TRANSCRIPTION.
+message SpeechTranscriptionConfig {
+  // *Required* The language of the supplied audio as a
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag.
+  // Example: "en-US".
+  // See [Language Support](https://cloud.google.com/speech/docs/languages)
+  // for a list of the currently supported language codes.
+  string language_code = 1;
+
+  // *Optional* Maximum number of recognition hypotheses to be returned.
+  // Specifically, the maximum number of `SpeechRecognitionAlternative` messages
+  // within each `SpeechRecognitionResult`. The server may return fewer than
+  // `max_alternatives`. Valid values are `0`-`30`. A value of `0` or `1` will
+  // return a maximum of one. If omitted, will return a maximum of one.
+  int32 max_alternatives = 2;
+
+  // *Optional* If set to `true`, the server will attempt to filter out
+  // profanities, replacing all but the initial character in each filtered word
+  // with asterisks, e.g. "f***". If set to `false` or omitted, profanities
+  // won't be filtered out.
+  bool filter_profanity = 3;
+
+  // *Optional* A means to provide context to assist the speech recognition.
+  repeated SpeechContext speech_contexts = 4;
+
+  // *Optional* If 'true', adds punctuation to recognition result hypotheses.
+  // This feature is only available in select languages. Setting this for
+  // requests in other languages has no effect at all. The default 'false' value
+  // does not add punctuation to result hypotheses. NOTE: "This is currently
+  // offered as an experimental service, complimentary to all users. In the
+  // future this may be exclusively available as a premium feature."
+  bool enable_automatic_punctuation = 5;
+
+  // *Optional* For file formats, such as MXF or MKV, supporting multiple audio
+  // tracks, specify up to two tracks. Default: track 0.
+  repeated int32 audio_tracks = 6;
+}
+
+// Provides "hints" to the speech recognizer to favor specific words and phrases
+// in the results.
+message SpeechContext {
+  // *Optional* A list of strings containing words and phrases "hints" so that
+  // the speech recognition is more likely to recognize them. This can be used
+  // to improve the accuracy for specific words and phrases, for example, if
+  // specific commands are typically spoken by the user. This can also be used
+  // to add additional words to the vocabulary of the recognizer. See
+  // [usage limits](https://cloud.google.com/speech/limits#content).
+  repeated string phrases = 1;
+}
+
+// A speech recognition result corresponding to a portion of the audio.
+message SpeechTranscription {
+  // Output only. May contain one or more recognition hypotheses (up to the
+  // maximum specified in `max_alternatives`).
+  // These alternatives are ordered in terms of accuracy, with the top (first)
+  // alternative being the most probable, as ranked by the recognizer.
+  repeated SpeechRecognitionAlternative alternatives = 1;
+}
+
+// Alternative hypotheses (a.k.a. n-best list).
+message SpeechRecognitionAlternative {
+  // Output only. Transcript text representing the words that the user spoke.
+  string transcript = 1;
+
+  // Output only. The confidence estimate between 0.0 and 1.0. A higher number
+  // indicates an estimated greater likelihood that the recognized words are
+  // correct. This field is typically provided only for the top hypothesis, and
+  // only for `is_final=true` results. Clients should not rely on the
+  // `confidence` field as it is not guaranteed to be accurate or consistent.
+  // The default of 0.0 is a sentinel value indicating `confidence` was not set.
+  float confidence = 2;
+
+  // Output only. A list of word-specific information for each recognized word.
+  repeated WordInfo words = 3;
+}
+
+// Word-specific information for recognized words. Word information is only
+// included in the response when certain request parameters are set, such
+// as `enable_word_time_offsets`.
+message WordInfo {
+  // Output only. Time offset relative to the beginning of the audio, and
+  // corresponding to the start of the spoken word. This field is only set if
+  // `enable_word_time_offsets=true` and only in the top hypothesis. This is an
+  // experimental feature and the accuracy of the time offset can vary.
+  google.protobuf.Duration start_time = 1;
+
+  // Output only. Time offset relative to the beginning of the audio, and
+  // corresponding to the end of the spoken word. This field is only set if
+  // `enable_word_time_offsets=true` and only in the top hypothesis. This is an
+  // experimental feature and the accuracy of the time offset can vary.
+  google.protobuf.Duration end_time = 2;
+
+  // Output only. The word corresponding to this set of information.
+  string word = 3;
+}
+
+// Video annotation feature.
+enum Feature {
+  // Unspecified.
+  FEATURE_UNSPECIFIED = 0;
+
+  // Label detection. Detect objects, such as dog or flower.
+  LABEL_DETECTION = 1;
+
+  // Shot change detection.
+  SHOT_CHANGE_DETECTION = 2;
+
+  // Explicit content detection.
+  EXPLICIT_CONTENT_DETECTION = 3;
+
+  // Speech transcription.
+  SPEECH_TRANSCRIPTION = 6;
+}
+
+// Label detection mode.
+enum LabelDetectionMode {
+  // Unspecified.
+  LABEL_DETECTION_MODE_UNSPECIFIED = 0;
+
+  // Detect shot-level labels.
+  SHOT_MODE = 1;
+
+  // Detect frame-level labels.
+  FRAME_MODE = 2;
+
+  // Detect both shot-level and frame-level labels.
+  SHOT_AND_FRAME_MODE = 3;
+}
+
+// Bucketized representation of likelihood.
+enum Likelihood {
+  // Unspecified likelihood.
+  LIKELIHOOD_UNSPECIFIED = 0;
+
+  // Very unlikely.
+  VERY_UNLIKELY = 1;
+
+  // Unlikely.
+  UNLIKELY = 2;
+
+  // Possible.
+  POSSIBLE = 3;
+
+  // Likely.
+  LIKELY = 4;
+
+  // Very likely.
+  VERY_LIKELY = 5;
+}
diff --git a/videointelligence/google/cloud/videointelligence_v1p2beta1/proto/video_intelligence.proto b/videointelligence/google/cloud/videointelligence_v1p2beta1/proto/video_intelligence.proto
new file mode 100644
index 000000000000..24bdb8eeb879
--- /dev/null
+++ b/videointelligence/google/cloud/videointelligence_v1p2beta1/proto/video_intelligence.proto
@@ -0,0 +1,433 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.videointelligence.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option csharp_namespace = "Google.Cloud.VideoIntelligence.V1P1Beta1";
+option go_package = "google.golang.org/genproto/googleapis/cloud/videointelligence/v1p1beta1;videointelligence";
+option java_multiple_files = true;
+option java_outer_classname = "VideoIntelligenceServiceProto";
+option java_package = "com.google.cloud.videointelligence.v1p1beta1";
+option php_namespace = "Google\\Cloud\\VideoIntelligence\\V1p1beta1";
+
+
+// Service that implements Google Cloud Video Intelligence API.
+service VideoIntelligenceService {
+  // Performs asynchronous video annotation. Progress and results can be
+  // retrieved through the `google.longrunning.Operations` interface.
+  // `Operation.metadata` contains `AnnotateVideoProgress` (progress).
+  // `Operation.response` contains `AnnotateVideoResponse` (results).
+  rpc AnnotateVideo(AnnotateVideoRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/videos:annotate"
+      body: "*"
+    };
+  }
+}
+
+// Video annotation request.
+message AnnotateVideoRequest {
+  // Input video location. Currently, only
+  // [Google Cloud Storage](https://cloud.google.com/storage/) URIs are
+  // supported, which must be specified in the following format:
+  // `gs://bucket-id/object-id` (other URI formats return
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+  // [Request URIs](/storage/docs/reference-uris).
+  // A video URI may include wildcards in `object-id`, and thus identify
+  // multiple videos. Supported wildcards: '*' to match 0 or more characters;
+  // '?' to match 1 character. If unset, the input video should be embedded
+  // in the request as `input_content`. If set, `input_content` should be unset.
+  string input_uri = 1;
+
+  // The video data bytes.
+  // If unset, the input video(s) should be specified via `input_uri`.
+  // If set, `input_uri` should be unset.
+  bytes input_content = 6;
+
+  // Requested video annotation features.
+  repeated Feature features = 2;
+
+  // Additional video context and/or feature-specific parameters.
+  VideoContext video_context = 3;
+
+  // Optional location where the output (in JSON format) should be stored.
+  // Currently, only [Google Cloud Storage](https://cloud.google.com/storage/)
+  // URIs are supported, which must be specified in the following format:
+  // `gs://bucket-id/object-id` (other URI formats return
+  // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT]). For more information, see
+  // [Request URIs](/storage/docs/reference-uris).
+  string output_uri = 4;
+
+  // Optional cloud region where annotation should take place. Supported cloud
+  // regions: `us-east1`, `us-west1`, `europe-west1`, `asia-east1`. If no region
+  // is specified, a region will be determined based on video file location.
+  string location_id = 5;
+}
+
+// Video context and/or feature-specific parameters.
+message VideoContext {
+  // Video segments to annotate. The segments may overlap and are not required
+  // to be contiguous or span the whole video. If unspecified, each video is
+  // treated as a single segment.
+  repeated VideoSegment segments = 1;
+
+  // Config for LABEL_DETECTION.
+  LabelDetectionConfig label_detection_config = 2;
+
+  // Config for SHOT_CHANGE_DETECTION.
+  ShotChangeDetectionConfig shot_change_detection_config = 3;
+
+  // Config for EXPLICIT_CONTENT_DETECTION.
+  ExplicitContentDetectionConfig explicit_content_detection_config = 4;
+
+  // Config for SPEECH_TRANSCRIPTION.
+  SpeechTranscriptionConfig speech_transcription_config = 6;
+}
+
+// Config for LABEL_DETECTION.
+message LabelDetectionConfig {
+  // What labels should be detected with LABEL_DETECTION, in addition to
+  // video-level labels or segment-level labels.
+  // If unspecified, defaults to `SHOT_MODE`.
+  LabelDetectionMode label_detection_mode = 1;
+
+  // Whether the video has been shot from a stationary (i.e. non-moving) camera.
+  // When set to true, might improve detection accuracy for moving objects.
+  // Should be used with `SHOT_AND_FRAME_MODE` enabled.
+  bool stationary_camera = 2;
+
+  // Model to use for label detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 3;
+}
+
+// Config for SHOT_CHANGE_DETECTION.
+message ShotChangeDetectionConfig {
+  // Model to use for shot change detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 1;
+}
+
+// Config for EXPLICIT_CONTENT_DETECTION.
+message ExplicitContentDetectionConfig {
+  // Model to use for explicit content detection.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 1;
+}
+
+// Video segment.
+message VideoSegment {
+  // Time-offset, relative to the beginning of the video,
+  // corresponding to the start of the segment (inclusive).
+  google.protobuf.Duration start_time_offset = 1;
+
+  // Time-offset, relative to the beginning of the video,
+  // corresponding to the end of the segment (inclusive).
+  google.protobuf.Duration end_time_offset = 2;
+}
+
+// Video segment level annotation results for label detection.
+message LabelSegment {
+  // Video segment where a label was detected.
+  VideoSegment segment = 1;
+
+  // Confidence that the label is accurate. Range: [0, 1].
+  float confidence = 2;
+}
+
+// Video frame level annotation results for label detection.
+message LabelFrame {
+  // Time-offset, relative to the beginning of the video, corresponding to the
+  // video frame for this location.
+  google.protobuf.Duration time_offset = 1;
+
+  // Confidence that the label is accurate. Range: [0, 1].
+  float confidence = 2;
+}
+
+// Detected entity from video analysis.
+message Entity {
+  // Opaque entity ID. Some IDs may be available in
+  // [Google Knowledge Graph Search
+  // API](https://developers.google.com/knowledge-graph/).
+  string entity_id = 1;
+
+  // Textual description, e.g. `Fixed-gear bicycle`.
+  string description = 2;
+
+  // Language code for `description` in BCP-47 format.
+  string language_code = 3;
+}
+
+// Label annotation.
+message LabelAnnotation {
+  // Detected entity.
+  Entity entity = 1;
+
+  // Common categories for the detected entity.
+  // E.g. when the label is `Terrier` the category is likely `dog`. And in some
+  // cases there might be more than one categories e.g. `Terrier` could also be
+  // a `pet`.
+  repeated Entity category_entities = 2;
+
+  // All video segments where a label was detected.
+  repeated LabelSegment segments = 3;
+
+  // All video frames where a label was detected.
+  repeated LabelFrame frames = 4;
+}
+
+// Video frame level annotation results for explicit content.
+message ExplicitContentFrame {
+  // Time-offset, relative to the beginning of the video, corresponding to the
+  // video frame for this location.
+  google.protobuf.Duration time_offset = 1;
+
+  // Likelihood of the pornography content..
+  Likelihood pornography_likelihood = 2;
+}
+
+// Explicit content annotation (based on per-frame visual signals only).
+// If no explicit content has been detected in a frame, no annotations are
+// present for that frame.
+message ExplicitContentAnnotation {
+  // All video frames where explicit content was detected.
+  repeated ExplicitContentFrame frames = 1;
+}
+
+// Annotation results for a single video.
+message VideoAnnotationResults {
+  // Output only. Video file location in
+  // [Google Cloud Storage](https://cloud.google.com/storage/).
+  string input_uri = 1;
+
+  // Label annotations on video level or user specified segment level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation segment_label_annotations = 2;
+
+  // Label annotations on shot level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation shot_label_annotations = 3;
+
+  // Label annotations on frame level.
+  // There is exactly one element for each unique label.
+  repeated LabelAnnotation frame_label_annotations = 4;
+
+  // Shot annotations. Each shot is represented as a video segment.
+  repeated VideoSegment shot_annotations = 6;
+
+  // Explicit content annotation.
+  ExplicitContentAnnotation explicit_annotation = 7;
+
+  // Speech transcription.
+  repeated SpeechTranscription speech_transcriptions = 11;
+
+  // Output only. If set, indicates an error. Note that for a single
+  // `AnnotateVideoRequest` some videos may succeed and some may fail.
+  google.rpc.Status error = 9;
+}
+
+// Video annotation response. Included in the `response`
+// field of the `Operation` returned by the `GetOperation`
+// call of the `google::longrunning::Operations` service.
+message AnnotateVideoResponse {
+  // Annotation results for all videos specified in `AnnotateVideoRequest`.
+  repeated VideoAnnotationResults annotation_results = 1;
+}
+
+// Annotation progress for a single video.
+message VideoAnnotationProgress {
+  // Output only. Video file location in
+  // [Google Cloud Storage](https://cloud.google.com/storage/).
+  string input_uri = 1;
+
+  // Output only. Approximate percentage processed thus far. Guaranteed to be
+  // 100 when fully processed.
+  int32 progress_percent = 2;
+
+  // Output only. Time when the request was received.
+  google.protobuf.Timestamp start_time = 3;
+
+  // Output only. Time of the most recent update.
+  google.protobuf.Timestamp update_time = 4;
+}
+
+// Video annotation progress. Included in the `metadata`
+// field of the `Operation` returned by the `GetOperation`
+// call of the `google::longrunning::Operations` service.
+message AnnotateVideoProgress {
+  // Progress metadata for all videos specified in `AnnotateVideoRequest`.
+  repeated VideoAnnotationProgress annotation_progress = 1;
+}
+
+// Config for SPEECH_TRANSCRIPTION.
+message SpeechTranscriptionConfig {
+  // *Required* The language of the supplied audio as a
+  // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag.
+  // Example: "en-US".
+  // See [Language Support](https://cloud.google.com/speech/docs/languages)
+  // for a list of the currently supported language codes.
+  string language_code = 1;
+
+  // *Optional* Maximum number of recognition hypotheses to be returned.
+  // Specifically, the maximum number of `SpeechRecognitionAlternative` messages
+  // within each `SpeechRecognitionResult`. The server may return fewer than
+  // `max_alternatives`. Valid values are `0`-`30`. A value of `0` or `1` will
+  // return a maximum of one. If omitted, will return a maximum of one.
+  int32 max_alternatives = 2;
+
+  // *Optional* If set to `true`, the server will attempt to filter out
+  // profanities, replacing all but the initial character in each filtered word
+  // with asterisks, e.g. "f***". If set to `false` or omitted, profanities
+  // won't be filtered out.
+  bool filter_profanity = 3;
+
+  // *Optional* A means to provide context to assist the speech recognition.
+  repeated SpeechContext speech_contexts = 4;
+
+  // *Optional* If 'true', adds punctuation to recognition result hypotheses.
+  // This feature is only available in select languages. Setting this for
+  // requests in other languages has no effect at all. The default 'false' value
+  // does not add punctuation to result hypotheses. NOTE: "This is currently
+  // offered as an experimental service, complimentary to all users. In the
+  // future this may be exclusively available as a premium feature."
+  bool enable_automatic_punctuation = 5;
+
+  // *Optional* For file formats, such as MXF or MKV, supporting multiple audio
+  // tracks, specify up to two tracks. Default: track 0.
+  repeated int32 audio_tracks = 6;
+}
+
+// Provides "hints" to the speech recognizer to favor specific words and phrases
+// in the results.
+message SpeechContext {
+  // *Optional* A list of strings containing words and phrases "hints" so that
+  // the speech recognition is more likely to recognize them. This can be used
+  // to improve the accuracy for specific words and phrases, for example, if
+  // specific commands are typically spoken by the user. This can also be used
+  // to add additional words to the vocabulary of the recognizer. See
+  // [usage limits](https://cloud.google.com/speech/limits#content).
+  repeated string phrases = 1;
+}
+
+// A speech recognition result corresponding to a portion of the audio.
+message SpeechTranscription {
+  // Output only. May contain one or more recognition hypotheses (up to the
+  // maximum specified in `max_alternatives`).
+  // These alternatives are ordered in terms of accuracy, with the top (first)
+  // alternative being the most probable, as ranked by the recognizer.
+  repeated SpeechRecognitionAlternative alternatives = 1;
+}
+
+// Alternative hypotheses (a.k.a. n-best list).
+message SpeechRecognitionAlternative {
+  // Output only. Transcript text representing the words that the user spoke.
+  string transcript = 1;
+
+  // Output only. The confidence estimate between 0.0 and 1.0. A higher number
+  // indicates an estimated greater likelihood that the recognized words are
+  // correct. This field is typically provided only for the top hypothesis, and
+  // only for `is_final=true` results. Clients should not rely on the
+  // `confidence` field as it is not guaranteed to be accurate or consistent.
+  // The default of 0.0 is a sentinel value indicating `confidence` was not set.
+  float confidence = 2;
+
+  // Output only. A list of word-specific information for each recognized word.
+  repeated WordInfo words = 3;
+}
+
+// Word-specific information for recognized words. Word information is only
+// included in the response when certain request parameters are set, such
+// as `enable_word_time_offsets`.
+message WordInfo {
+  // Output only. Time offset relative to the beginning of the audio, and
+  // corresponding to the start of the spoken word. This field is only set if
+  // `enable_word_time_offsets=true` and only in the top hypothesis. This is an
+  // experimental feature and the accuracy of the time offset can vary.
+  google.protobuf.Duration start_time = 1;
+
+  // Output only. Time offset relative to the beginning of the audio, and
+  // corresponding to the end of the spoken word. This field is only set if
+  // `enable_word_time_offsets=true` and only in the top hypothesis. This is an
+  // experimental feature and the accuracy of the time offset can vary.
+  google.protobuf.Duration end_time = 2;
+
+  // Output only. The word corresponding to this set of information.
+  string word = 3;
+}
+
+// Video annotation feature.
+enum Feature {
+  // Unspecified.
+  FEATURE_UNSPECIFIED = 0;
+
+  // Label detection. Detect objects, such as dog or flower.
+  LABEL_DETECTION = 1;
+
+  // Shot change detection.
+  SHOT_CHANGE_DETECTION = 2;
+
+  // Explicit content detection.
+  EXPLICIT_CONTENT_DETECTION = 3;
+
+  // Speech transcription.
+  SPEECH_TRANSCRIPTION = 6;
+}
+
+// Label detection mode.
+enum LabelDetectionMode {
+  // Unspecified.
+  LABEL_DETECTION_MODE_UNSPECIFIED = 0;
+
+  // Detect shot-level labels.
+  SHOT_MODE = 1;
+
+  // Detect frame-level labels.
+  FRAME_MODE = 2;
+
+  // Detect both shot-level and frame-level labels.
+  SHOT_AND_FRAME_MODE = 3;
+}
+
+// Bucketized representation of likelihood.
+enum Likelihood {
+  // Unspecified likelihood.
+  LIKELIHOOD_UNSPECIFIED = 0;
+
+  // Very unlikely.
+  VERY_UNLIKELY = 1;
+
+  // Unlikely.
+  UNLIKELY = 2;
+
+  // Possible.
+  POSSIBLE = 3;
+
+  // Likely.
+  LIKELY = 4;
+
+  // Very likely.
+  VERY_LIKELY = 5;
+}
diff --git a/videointelligence/synth.metadata b/videointelligence/synth.metadata
index e2ae393200b4..ab1929a22e50 100644
--- a/videointelligence/synth.metadata
+++ b/videointelligence/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:31:49.525364Z",
+  "updateTime": "2019-01-24T17:45:30.456169Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/videointelligence/synth.py b/videointelligence/synth.py
index da1e5c52d599..7f23300dda1a 100644
--- a/videointelligence/synth.py
+++ b/videointelligence/synth.py
@@ -28,7 +28,10 @@
 # ----------------------------------------------------------------------------
 for version in versions:
     library = gapic.py_library(
-        "videointelligence", version, artman_output_name=f"video-intelligence-{version}"
+        "videointelligence",
+        version,
+        artman_output_name=f"video-intelligence-{version}",
+        include_protos=True,
     )
 
     # TODO: stop excluding tests and nox.py (excluded as we lack system tests)
diff --git a/vision/google/cloud/vision_v1/proto/geometry.proto b/vision/google/cloud/vision_v1/proto/geometry.proto
new file mode 100644
index 000000000000..6d46d9c342ec
--- /dev/null
+++ b/vision/google/cloud/vision_v1/proto/geometry.proto
@@ -0,0 +1,53 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "GeometryProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// A vertex represents a 2D point in the image.
+// NOTE: the vertex coordinates are in the same scale as the original image.
+message Vertex {
+  // X coordinate.
+  int32 x = 1;
+
+  // Y coordinate.
+  int32 y = 2;
+}
+
+// A bounding polygon for the detected image annotation.
+message BoundingPoly {
+  // The bounding polygon vertices.
+  repeated Vertex vertices = 1;
+}
+
+// A 3D position in the image, used primarily for Face detection landmarks.
+// A valid Position must have both x and y coordinates.
+// The position coordinates are in the same scale as the original image.
+message Position {
+  // X coordinate.
+  float x = 1;
+
+  // Y coordinate.
+  float y = 2;
+
+  // Z coordinate (or depth).
+  float z = 3;
+}
diff --git a/vision/google/cloud/vision_v1/proto/image_annotator.proto b/vision/google/cloud/vision_v1/proto/image_annotator.proto
new file mode 100644
index 000000000000..73b8db853aad
--- /dev/null
+++ b/vision/google/cloud/vision_v1/proto/image_annotator.proto
@@ -0,0 +1,591 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p1beta1/geometry.proto";
+import "google/cloud/vision/v1p1beta1/text_annotation.proto";
+import "google/cloud/vision/v1p1beta1/web_detection.proto";
+import "google/rpc/status.proto";
+import "google/type/color.proto";
+import "google/type/latlng.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ImageAnnotatorProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// Service that performs Google Cloud Vision API detection tasks over client
+// images, such as face, landmark, logo, label, and text detection. The
+// ImageAnnotator service returns detected entities from the images.
+service ImageAnnotator {
+  // Run image detection and annotation for a batch of images.
+  rpc BatchAnnotateImages(BatchAnnotateImagesRequest)
+      returns (BatchAnnotateImagesResponse) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/images:annotate"
+      body: "*"
+    };
+  }
+}
+
+// Users describe the type of Google Cloud Vision API tasks to perform over
+// images by using *Feature*s. Each Feature indicates a type of image
+// detection task to perform. Features encode the Cloud Vision API
+// vertical to operate on and the number of top-scoring results to return.
+message Feature {
+  // Type of image feature.
+  enum Type {
+    // Unspecified feature type.
+    TYPE_UNSPECIFIED = 0;
+
+    // Run face detection.
+    FACE_DETECTION = 1;
+
+    // Run landmark detection.
+    LANDMARK_DETECTION = 2;
+
+    // Run logo detection.
+    LOGO_DETECTION = 3;
+
+    // Run label detection.
+    LABEL_DETECTION = 4;
+
+    // Run OCR.
+    TEXT_DETECTION = 5;
+
+    // Run dense text document OCR. Takes precedence when both
+    // DOCUMENT_TEXT_DETECTION and TEXT_DETECTION are present.
+    DOCUMENT_TEXT_DETECTION = 11;
+
+    // Run computer vision models to compute image safe-search properties.
+    SAFE_SEARCH_DETECTION = 6;
+
+    // Compute a set of image properties, such as the image's dominant colors.
+    IMAGE_PROPERTIES = 7;
+
+    // Run crop hints.
+    CROP_HINTS = 9;
+
+    // Run web detection.
+    WEB_DETECTION = 10;
+  }
+
+  // The feature type.
+  Type type = 1;
+
+  // Maximum number of results of this type.
+  int32 max_results = 2;
+
+  // Model to use for the feature.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 3;
+}
+
+// External image source (Google Cloud Storage image location).
+message ImageSource {
+  // NOTE: For new code `image_uri` below is preferred.
+  // Google Cloud Storage image URI, which must be in the following form:
+  // `gs://bucket_name/object_name` (for details, see
+  // [Google Cloud Storage Request
+  // URIs](https://cloud.google.com/storage/docs/reference-uris)).
+  // NOTE: Cloud Storage object versioning is not supported.
+  string gcs_image_uri = 1;
+
+  // Image URI which supports:
+  // 1) Google Cloud Storage image URI, which must be in the following form:
+  // `gs://bucket_name/object_name` (for details, see
+  // [Google Cloud Storage Request
+  // URIs](https://cloud.google.com/storage/docs/reference-uris)).
+  // NOTE: Cloud Storage object versioning is not supported.
+  // 2) Publicly accessible image HTTP/HTTPS URL.
+  // This is preferred over the legacy `gcs_image_uri` above. When both
+  // `gcs_image_uri` and `image_uri` are specified, `image_uri` takes
+  // precedence.
+  string image_uri = 2;
+}
+
+// Client image to perform Google Cloud Vision API tasks over.
+message Image {
+  // Image content, represented as a stream of bytes.
+  // Note: as with all `bytes` fields, protobuffers use a pure binary
+  // representation, whereas JSON representations use base64.
+  bytes content = 1;
+
+  // Google Cloud Storage image location. If both `content` and `source`
+  // are provided for an image, `content` takes precedence and is
+  // used to perform the image annotation request.
+  ImageSource source = 2;
+}
+
+// A face annotation object contains the results of face detection.
+message FaceAnnotation {
+  // A face-specific landmark (for example, a face feature).
+  message Landmark {
+    // Face landmark (feature) type.
+    // Left and right are defined from the vantage of the viewer of the image
+    // without considering mirror projections typical of photos. So, `LEFT_EYE`,
+    // typically, is the person's right eye.
+    enum Type {
+      // Unknown face landmark detected. Should not be filled.
+      UNKNOWN_LANDMARK = 0;
+
+      // Left eye.
+      LEFT_EYE = 1;
+
+      // Right eye.
+      RIGHT_EYE = 2;
+
+      // Left of left eyebrow.
+      LEFT_OF_LEFT_EYEBROW = 3;
+
+      // Right of left eyebrow.
+      RIGHT_OF_LEFT_EYEBROW = 4;
+
+      // Left of right eyebrow.
+      LEFT_OF_RIGHT_EYEBROW = 5;
+
+      // Right of right eyebrow.
+      RIGHT_OF_RIGHT_EYEBROW = 6;
+
+      // Midpoint between eyes.
+      MIDPOINT_BETWEEN_EYES = 7;
+
+      // Nose tip.
+      NOSE_TIP = 8;
+
+      // Upper lip.
+      UPPER_LIP = 9;
+
+      // Lower lip.
+      LOWER_LIP = 10;
+
+      // Mouth left.
+      MOUTH_LEFT = 11;
+
+      // Mouth right.
+      MOUTH_RIGHT = 12;
+
+      // Mouth center.
+      MOUTH_CENTER = 13;
+
+      // Nose, bottom right.
+      NOSE_BOTTOM_RIGHT = 14;
+
+      // Nose, bottom left.
+      NOSE_BOTTOM_LEFT = 15;
+
+      // Nose, bottom center.
+      NOSE_BOTTOM_CENTER = 16;
+
+      // Left eye, top boundary.
+      LEFT_EYE_TOP_BOUNDARY = 17;
+
+      // Left eye, right corner.
+      LEFT_EYE_RIGHT_CORNER = 18;
+
+      // Left eye, bottom boundary.
+      LEFT_EYE_BOTTOM_BOUNDARY = 19;
+
+      // Left eye, left corner.
+      LEFT_EYE_LEFT_CORNER = 20;
+
+      // Right eye, top boundary.
+      RIGHT_EYE_TOP_BOUNDARY = 21;
+
+      // Right eye, right corner.
+      RIGHT_EYE_RIGHT_CORNER = 22;
+
+      // Right eye, bottom boundary.
+      RIGHT_EYE_BOTTOM_BOUNDARY = 23;
+
+      // Right eye, left corner.
+      RIGHT_EYE_LEFT_CORNER = 24;
+
+      // Left eyebrow, upper midpoint.
+      LEFT_EYEBROW_UPPER_MIDPOINT = 25;
+
+      // Right eyebrow, upper midpoint.
+      RIGHT_EYEBROW_UPPER_MIDPOINT = 26;
+
+      // Left ear tragion.
+      LEFT_EAR_TRAGION = 27;
+
+      // Right ear tragion.
+      RIGHT_EAR_TRAGION = 28;
+
+      // Left eye pupil.
+      LEFT_EYE_PUPIL = 29;
+
+      // Right eye pupil.
+      RIGHT_EYE_PUPIL = 30;
+
+      // Forehead glabella.
+      FOREHEAD_GLABELLA = 31;
+
+      // Chin gnathion.
+      CHIN_GNATHION = 32;
+
+      // Chin left gonion.
+      CHIN_LEFT_GONION = 33;
+
+      // Chin right gonion.
+      CHIN_RIGHT_GONION = 34;
+    }
+
+    // Face landmark type.
+    Type type = 3;
+
+    // Face landmark position.
+    Position position = 4;
+  }
+
+  // The bounding polygon around the face. The coordinates of the bounding box
+  // are in the original image's scale, as returned in `ImageParams`.
+  // The bounding box is computed to "frame" the face in accordance with human
+  // expectations. It is based on the landmarker results.
+  // Note that one or more x and/or y coordinates may not be generated in the
+  // `BoundingPoly` (the polygon will be unbounded) if only a partial face
+  // appears in the image to be annotated.
+  BoundingPoly bounding_poly = 1;
+
+  // The `fd_bounding_poly` bounding polygon is tighter than the
+  // `boundingPoly`, and encloses only the skin part of the face. Typically, it
+  // is used to eliminate the face from any image analysis that detects the
+  // "amount of skin" visible in an image. It is not based on the
+  // landmarker results, only on the initial face detection, hence
+  // the <code>fd</code> (face detection) prefix.
+  BoundingPoly fd_bounding_poly = 2;
+
+  // Detected face landmarks.
+  repeated Landmark landmarks = 3;
+
+  // Roll angle, which indicates the amount of clockwise/anti-clockwise rotation
+  // of the face relative to the image vertical about the axis perpendicular to
+  // the face. Range [-180,180].
+  float roll_angle = 4;
+
+  // Yaw angle, which indicates the leftward/rightward angle that the face is
+  // pointing relative to the vertical plane perpendicular to the image. Range
+  // [-180,180].
+  float pan_angle = 5;
+
+  // Pitch angle, which indicates the upwards/downwards angle that the face is
+  // pointing relative to the image's horizontal plane. Range [-180,180].
+  float tilt_angle = 6;
+
+  // Detection confidence. Range [0, 1].
+  float detection_confidence = 7;
+
+  // Face landmarking confidence. Range [0, 1].
+  float landmarking_confidence = 8;
+
+  // Joy likelihood.
+  Likelihood joy_likelihood = 9;
+
+  // Sorrow likelihood.
+  Likelihood sorrow_likelihood = 10;
+
+  // Anger likelihood.
+  Likelihood anger_likelihood = 11;
+
+  // Surprise likelihood.
+  Likelihood surprise_likelihood = 12;
+
+  // Under-exposed likelihood.
+  Likelihood under_exposed_likelihood = 13;
+
+  // Blurred likelihood.
+  Likelihood blurred_likelihood = 14;
+
+  // Headwear likelihood.
+  Likelihood headwear_likelihood = 15;
+}
+
+// Detected entity location information.
+message LocationInfo {
+  // lat/long location coordinates.
+  google.type.LatLng lat_lng = 1;
+}
+
+// A `Property` consists of a user-supplied name/value pair.
+message Property {
+  // Name of the property.
+  string name = 1;
+
+  // Value of the property.
+  string value = 2;
+
+  // Value of numeric properties.
+  uint64 uint64_value = 3;
+}
+
+// Set of detected entity features.
+message EntityAnnotation {
+  // Opaque entity ID. Some IDs may be available in
+  // [Google Knowledge Graph Search API](https://developers.google.com/knowledge-graph/).
+  string mid = 1;
+
+  // The language code for the locale in which the entity textual
+  // `description` is expressed.
+  string locale = 2;
+
+  // Entity textual description, expressed in its `locale` language.
+  string description = 3;
+
+  // Overall score of the result. Range [0, 1].
+  float score = 4;
+
+  // The accuracy of the entity detection in an image.
+  // For example, for an image in which the "Eiffel Tower" entity is detected,
+  // this field represents the confidence that there is a tower in the query
+  // image. Range [0, 1].
+  float confidence = 5;
+
+  // The relevancy of the ICA (Image Content Annotation) label to the
+  // image. For example, the relevancy of "tower" is likely higher to an image
+  // containing the detected "Eiffel Tower" than to an image containing a
+  // detected distant towering building, even though the confidence that
+  // there is a tower in each image may be the same. Range [0, 1].
+  float topicality = 6;
+
+  // Image region to which this entity belongs. Not produced
+  // for `LABEL_DETECTION` features.
+  BoundingPoly bounding_poly = 7;
+
+  // The location information for the detected entity. Multiple
+  // `LocationInfo` elements can be present because one location may
+  // indicate the location of the scene in the image, and another location
+  // may indicate the location of the place where the image was taken.
+  // Location information is usually present for landmarks.
+  repeated LocationInfo locations = 8;
+
+  // Some entities may have optional user-supplied `Property` (name/value)
+  // fields, such a score or string that qualifies the entity.
+  repeated Property properties = 9;
+}
+
+// Set of features pertaining to the image, computed by computer vision
+// methods over safe-search verticals (for example, adult, spoof, medical,
+// violence).
+message SafeSearchAnnotation {
+  // Represents the adult content likelihood for the image. Adult content may
+  // contain elements such as nudity, pornographic images or cartoons, or
+  // sexual activities.
+  Likelihood adult = 1;
+
+  // Spoof likelihood. The likelihood that an modification
+  // was made to the image's canonical version to make it appear
+  // funny or offensive.
+  Likelihood spoof = 2;
+
+  // Likelihood that this is a medical image.
+  Likelihood medical = 3;
+
+  // Likelihood that this image contains violent content.
+  Likelihood violence = 4;
+
+  // Likelihood that the request image contains racy content. Racy content may
+  // include (but is not limited to) skimpy or sheer clothing, strategically
+  // covered nudity, lewd or provocative poses, or close-ups of sensitive
+  // body areas.
+  Likelihood racy = 9;
+}
+
+// Rectangle determined by min and max `LatLng` pairs.
+message LatLongRect {
+  // Min lat/long pair.
+  google.type.LatLng min_lat_lng = 1;
+
+  // Max lat/long pair.
+  google.type.LatLng max_lat_lng = 2;
+}
+
+// Color information consists of RGB channels, score, and the fraction of
+// the image that the color occupies in the image.
+message ColorInfo {
+  // RGB components of the color.
+  google.type.Color color = 1;
+
+  // Image-specific score for this color. Value in range [0, 1].
+  float score = 2;
+
+  // The fraction of pixels the color occupies in the image.
+  // Value in range [0, 1].
+  float pixel_fraction = 3;
+}
+
+// Set of dominant colors and their corresponding scores.
+message DominantColorsAnnotation {
+  // RGB color values with their score and pixel fraction.
+  repeated ColorInfo colors = 1;
+}
+
+// Stores image properties, such as dominant colors.
+message ImageProperties {
+  // If present, dominant colors completed successfully.
+  DominantColorsAnnotation dominant_colors = 1;
+}
+
+// Single crop hint that is used to generate a new crop when serving an image.
+message CropHint {
+  // The bounding polygon for the crop region. The coordinates of the bounding
+  // box are in the original image's scale, as returned in `ImageParams`.
+  BoundingPoly bounding_poly = 1;
+
+  // Confidence of this being a salient region.  Range [0, 1].
+  float confidence = 2;
+
+  // Fraction of importance of this salient region with respect to the original
+  // image.
+  float importance_fraction = 3;
+}
+
+// Set of crop hints that are used to generate new crops when serving images.
+message CropHintsAnnotation {
+  // Crop hint results.
+  repeated CropHint crop_hints = 1;
+}
+
+// Parameters for crop hints annotation request.
+message CropHintsParams {
+  // Aspect ratios in floats, representing the ratio of the width to the height
+  // of the image. For example, if the desired aspect ratio is 4/3, the
+  // corresponding float value should be 1.33333.  If not specified, the
+  // best possible crop is returned. The number of provided aspect ratios is
+  // limited to a maximum of 16; any aspect ratios provided after the 16th are
+  // ignored.
+  repeated float aspect_ratios = 1;
+}
+
+// Parameters for web detection request.
+message WebDetectionParams {
+  // Whether to include results derived from the geo information in the image.
+  bool include_geo_results = 2;
+}
+
+// Image context and/or feature-specific parameters.
+message ImageContext {
+  // lat/long rectangle that specifies the location of the image.
+  LatLongRect lat_long_rect = 1;
+
+  // List of languages to use for TEXT_DETECTION. In most cases, an empty value
+  // yields the best results since it enables automatic language detection. For
+  // languages based on the Latin alphabet, setting `language_hints` is not
+  // needed. In rare cases, when the language of the text in the image is known,
+  // setting a hint will help get better results (although it will be a
+  // significant hindrance if the hint is wrong). Text detection returns an
+  // error if one or more of the specified languages is not one of the
+  // [supported languages](/vision/docs/languages).
+  repeated string language_hints = 2;
+
+  // Parameters for crop hints annotation request.
+  CropHintsParams crop_hints_params = 4;
+
+  // Parameters for web detection.
+  WebDetectionParams web_detection_params = 6;
+}
+
+// Request for performing Google Cloud Vision API tasks over a user-provided
+// image, with user-requested features.
+message AnnotateImageRequest {
+  // The image to be processed.
+  Image image = 1;
+
+  // Requested features.
+  repeated Feature features = 2;
+
+  // Additional context that may accompany the image.
+  ImageContext image_context = 3;
+}
+
+// Response to an image annotation request.
+message AnnotateImageResponse {
+  // If present, face detection has completed successfully.
+  repeated FaceAnnotation face_annotations = 1;
+
+  // If present, landmark detection has completed successfully.
+  repeated EntityAnnotation landmark_annotations = 2;
+
+  // If present, logo detection has completed successfully.
+  repeated EntityAnnotation logo_annotations = 3;
+
+  // If present, label detection has completed successfully.
+  repeated EntityAnnotation label_annotations = 4;
+
+  // If present, text (OCR) detection has completed successfully.
+  repeated EntityAnnotation text_annotations = 5;
+
+  // If present, text (OCR) detection or document (OCR) text detection has
+  // completed successfully.
+  // This annotation provides the structural hierarchy for the OCR detected
+  // text.
+  TextAnnotation full_text_annotation = 12;
+
+  // If present, safe-search annotation has completed successfully.
+  SafeSearchAnnotation safe_search_annotation = 6;
+
+  // If present, image properties were extracted successfully.
+  ImageProperties image_properties_annotation = 8;
+
+  // If present, crop hints have completed successfully.
+  CropHintsAnnotation crop_hints_annotation = 11;
+
+  // If present, web detection has completed successfully.
+  WebDetection web_detection = 13;
+
+  // If set, represents the error message for the operation.
+  // Note that filled-in image annotations are guaranteed to be
+  // correct, even when `error` is set.
+  google.rpc.Status error = 9;
+}
+
+// Multiple image annotation requests are batched into a single service call.
+message BatchAnnotateImagesRequest {
+  // Individual image annotation requests for this batch.
+  repeated AnnotateImageRequest requests = 1;
+}
+
+// Response to a batch image annotation request.
+message BatchAnnotateImagesResponse {
+  // Individual responses to image annotation requests within the batch.
+  repeated AnnotateImageResponse responses = 1;
+}
+
+// A bucketized representation of likelihood, which is intended to give clients
+// highly stable results across model upgrades.
+enum Likelihood {
+  // Unknown likelihood.
+  UNKNOWN = 0;
+
+  // It is very unlikely that the image belongs to the specified vertical.
+  VERY_UNLIKELY = 1;
+
+  // It is unlikely that the image belongs to the specified vertical.
+  UNLIKELY = 2;
+
+  // It is possible that the image belongs to the specified vertical.
+  POSSIBLE = 3;
+
+  // It is likely that the image belongs to the specified vertical.
+  LIKELY = 4;
+
+  // It is very likely that the image belongs to the specified vertical.
+  VERY_LIKELY = 5;
+}
diff --git a/vision/google/cloud/vision_v1/proto/product_search.proto b/vision/google/cloud/vision_v1/proto/product_search.proto
new file mode 100644
index 000000000000..85e4e0784e1c
--- /dev/null
+++ b/vision/google/cloud/vision_v1/proto/product_search.proto
@@ -0,0 +1,161 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p3beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p3beta1/geometry.proto";
+import "google/cloud/vision/v1p3beta1/product_search_service.proto";
+import "google/protobuf/timestamp.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ProductSearchProto";
+option java_package = "com.google.cloud.vision.v1p3beta1";
+
+
+// Parameters for a product search request.
+message ProductSearchParams {
+  // The resource name of the catalog to search.
+  //
+  // Format is: `productSearch/catalogs/CATALOG_NAME`.
+  string catalog_name = 1;
+
+  // The category to search in.
+  // Optional. It is inferred by the system if it is not specified.
+  // [Deprecated] Use `product_category`.
+  ProductSearchCategory category = 2;
+
+  // The product category to search in.
+  // Optional. It is inferred by the system if it is not specified.
+  // Supported values are `bag`, `shoe`, `sunglasses`, `dress`, `outerwear`,
+  // `skirt`, `top`, `shorts`, and `pants`.
+  string product_category = 5;
+
+  // The bounding polygon around the area of interest in the image.
+  // Optional. If it is not specified, system discretion will be applied.
+  // [Deprecated] Use `bounding_poly`.
+  NormalizedBoundingPoly normalized_bounding_poly = 3;
+
+  // The bounding polygon around the area of interest in the image.
+  // Optional. If it is not specified, system discretion will be applied.
+  BoundingPoly bounding_poly = 9;
+
+  // Specifies the verbosity of the  product search results.
+  // Optional. Defaults to `BASIC`.
+  ProductSearchResultsView view = 4;
+
+  // The resource name of a [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] to be searched for similar images.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`.
+  string product_set = 6;
+
+  // The list of product categories to search in. Currently, we only consider
+  // the first category, and either "homegoods" or "apparel" should be
+  // specified.
+  repeated string product_categories = 7;
+
+  // The filtering expression. This can be used to restrict search results based
+  // on Product labels. We currently support an AND of OR of key-value
+  // expressions, where each expression within an OR must have the same key.
+  //
+  // For example, "(color = red OR color = blue) AND brand = Google" is
+  // acceptable, but not "(color = red OR brand = Google)" or "color: red".
+  string filter = 8;
+}
+
+// Results for a product search request.
+message ProductSearchResults {
+  // Information about a product.
+  message ProductInfo {
+    // Product ID.
+    string product_id = 1;
+
+    // The URI of the image which matched the query image.
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    string image_uri = 2;
+
+    // A confidence level on the match, ranging from 0 (no confidence) to
+    // 1 (full confidence).
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    float score = 3;
+  }
+
+  // Information about a product.
+  message Result {
+    // The Product.
+    Product product = 1;
+
+    // A confidence level on the match, ranging from 0 (no confidence) to
+    // 1 (full confidence).
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    float score = 2;
+
+    // The resource name of the image from the product that is the closest match
+    // to the query.
+    string image = 3;
+  }
+
+  // Product category.
+  // [Deprecated] Use `product_category`.
+  ProductSearchCategory category = 1;
+
+  // Product category.
+  // Supported values are `bag` and `shoe`.
+  // [Deprecated] `product_category` is provided in each Product.
+  string product_category = 4;
+
+  // Timestamp of the index which provided these results. Changes made after
+  // this time are not reflected in the current results.
+  google.protobuf.Timestamp index_time = 2;
+
+  // List of detected products.
+  repeated ProductInfo products = 3;
+
+  // List of results, one for each product match.
+  repeated Result results = 5;
+}
+
+// Supported product search categories.
+enum ProductSearchCategory {
+  // Default value used when a category is not specified.
+  PRODUCT_SEARCH_CATEGORY_UNSPECIFIED = 0;
+
+  // Shoes category.
+  SHOES = 1;
+
+  // Bags category.
+  BAGS = 2;
+}
+
+// Specifies the fields to include in product search results.
+enum ProductSearchResultsView {
+  // Product search results contain only `product_category` and `product_id`.
+  // Default value.
+  BASIC = 0;
+
+  // Product search results contain `product_category`, `product_id`,
+  // `image_uri`, and `score`.
+  FULL = 1;
+}
diff --git a/vision/google/cloud/vision_v1/proto/product_search_service.proto b/vision/google/cloud/vision_v1/proto/product_search_service.proto
new file mode 100644
index 000000000000..90388e36e228
--- /dev/null
+++ b/vision/google/cloud/vision_v1/proto/product_search_service.proto
@@ -0,0 +1,825 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p3beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p3beta1/geometry.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ProductSearchServiceProto";
+option java_package = "com.google.cloud.vision.v1p3beta1";
+
+
+// Manages Products and ProductSets of reference images for use in product
+// search. It uses the following resource model:
+//
+// - The API has a collection of [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] resources, named
+// `projects/*/locations/*/productSets/*`, which acts as a way to put different
+// products into groups to limit identification.
+//
+// In parallel,
+//
+// - The API has a collection of [Product][google.cloud.vision.v1p3beta1.Product] resources, named
+//   `projects/*/locations/*/products/*`
+//
+// - Each [Product][google.cloud.vision.v1p3beta1.Product] has a collection of [ReferenceImage][google.cloud.vision.v1p3beta1.ReferenceImage] resources, named
+//   `projects/*/locations/*/products/*/referenceImages/*`
+service ProductSearch {
+  // Creates and returns a new ProductSet resource.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if display_name is missing, or is longer than
+  //   4096 characters.
+  rpc CreateProductSet(CreateProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/productSets"
+      body: "product_set"
+    };
+  }
+
+  // Lists ProductSets in an unspecified order.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100, or less
+  //   than 1.
+  rpc ListProductSets(ListProductSetsRequest) returns (ListProductSetsResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*}/productSets"
+    };
+  }
+
+  // Gets information associated with a ProductSet.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  rpc GetProductSet(GetProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}"
+    };
+  }
+
+  // Makes changes to a ProductSet resource.
+  // Only display_name can be updated currently.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  // * Returns INVALID_ARGUMENT if display_name is present in update_mask but
+  //   missing from the request or longer than 4096 characters.
+  rpc UpdateProductSet(UpdateProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      patch: "/v1p3beta1/{product_set.name=projects/*/locations/*/productSets/*}"
+      body: "product_set"
+    };
+  }
+
+  // Permanently deletes a ProductSet. All Products and ReferenceImages in the
+  // ProductSet will be deleted.
+  //
+  // The actual image files are not deleted from Google Cloud Storage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  rpc DeleteProductSet(DeleteProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}"
+    };
+  }
+
+  // Creates and returns a new product resource.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if display_name is missing or longer than 4096
+  //   characters.
+  // * Returns INVALID_ARGUMENT if description is longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if product_category is missing or invalid.
+  rpc CreateProduct(CreateProductRequest) returns (Product) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/products"
+      body: "product"
+    };
+  }
+
+  // Lists products in an unspecified order.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
+  rpc ListProducts(ListProductsRequest) returns (ListProductsResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*}/products"
+    };
+  }
+
+  // Gets information associated with a Product.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product does not exist.
+  rpc GetProduct(GetProductRequest) returns (Product) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/products/*}"
+    };
+  }
+
+  // Makes changes to a Product resource.
+  // Only display_name, description and labels can be updated right now.
+  //
+  // If labels are updated, the change will not be reflected in queries until
+  // the next index time.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product does not exist.
+  // * Returns INVALID_ARGUMENT if display_name is present in update_mask but is
+  //   missing from the request or longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if description is present in update_mask but is
+  //   longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if product_category is present in update_mask.
+  rpc UpdateProduct(UpdateProductRequest) returns (Product) {
+    option (google.api.http) = {
+      patch: "/v1p3beta1/{product.name=projects/*/locations/*/products/*}"
+      body: "product"
+    };
+  }
+
+  // Permanently deletes a product and its reference images.
+  //
+  // Metadata of the product and all its images will be deleted right away, but
+  // search queries against ProductSets containing the product may still work
+  // until all related caches are refreshed.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the product does not exist.
+  rpc DeleteProduct(DeleteProductRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/products/*}"
+    };
+  }
+
+  // Creates and returns a new ReferenceImage resource.
+  //
+  // The `bounding_poly` field is optional. If `bounding_poly` is not specified,
+  // the system will try to detect regions of interest in the image that are
+  // compatible with the product_category on the parent product. If it is
+  // specified, detection is ALWAYS skipped. The system converts polygons into
+  // non-rotated rectangles.
+  //
+  // Note that the pipeline will resize the image if the image resolution is too
+  // large to process (above 50MP).
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if the image_uri is missing or longer than 4096
+  //   characters.
+  // * Returns INVALID_ARGUMENT if the product does not exist.
+  // * Returns INVALID_ARGUMENT if bounding_poly is not provided, and nothing
+  //   compatible with the parent product's product_category is detected.
+  // * Returns INVALID_ARGUMENT if bounding_poly contains more than 10 polygons.
+  rpc CreateReferenceImage(CreateReferenceImageRequest) returns (ReferenceImage) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages"
+      body: "reference_image"
+    };
+  }
+
+  // Permanently deletes a reference image.
+  //
+  // The image metadata will be deleted right away, but search queries
+  // against ProductSets containing the image may still work until all related
+  // caches are refreshed.
+  //
+  // The actual image files are not deleted from Google Cloud Storage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the reference image does not exist.
+  rpc DeleteReferenceImage(DeleteReferenceImageRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}"
+    };
+  }
+
+  // Lists reference images.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the parent product does not exist.
+  // * Returns INVALID_ARGUMENT if the page_size is greater than 100, or less
+  //   than 1.
+  rpc ListReferenceImages(ListReferenceImagesRequest) returns (ListReferenceImagesResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages"
+    };
+  }
+
+  // Gets information associated with a ReferenceImage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the specified image does not exist.
+  rpc GetReferenceImage(GetReferenceImageRequest) returns (ReferenceImage) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}"
+    };
+  }
+
+  // Adds a Product to the specified ProductSet. If the Product is already
+  // present, no change is made.
+  //
+  // One Product can be added to at most 100 ProductSets.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product or the ProductSet doesn't exist.
+  rpc AddProductToProductSet(AddProductToProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}:addProduct"
+      body: "*"
+    };
+  }
+
+  // Removes a Product from the specified ProductSet.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND If the Product is not found under the ProductSet.
+  rpc RemoveProductFromProductSet(RemoveProductFromProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}:removeProduct"
+      body: "*"
+    };
+  }
+
+  // Lists the Products in a ProductSet, in an unspecified order. If the
+  // ProductSet does not exist, the products field of the response will be
+  // empty.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
+  rpc ListProductsInProductSet(ListProductsInProductSetRequest) returns (ListProductsInProductSetResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}/products"
+    };
+  }
+
+  // Asynchronous API that imports a list of reference images to specified
+  // product sets based on a list of image information.
+  //
+  // The [google.longrunning.Operation][google.longrunning.Operation] API can be used to keep track of the
+  // progress and results of the request.
+  // `Operation.metadata` contains `BatchOperationMetadata`. (progress)
+  // `Operation.response` contains `ImportProductSetsResponse`. (results)
+  //
+  // The input source of this method is a csv file on Google Cloud Storage.
+  // For the format of the csv file please see
+  // [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p3beta1.ImportProductSetsGcsSource.csv_file_uri].
+  rpc ImportProductSets(ImportProductSetsRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/productSets:import"
+      body: "*"
+    };
+  }
+}
+
+// A Product contains ReferenceImages.
+message Product {
+  // A product label represented as a key-value pair.
+  message KeyValue {
+    // The key of the label attached to the product. Cannot be empty and cannot
+    // exceed 128 bytes.
+    string key = 1;
+
+    // The value of the label attached to the product. Cannot be empty and
+    // cannot exceed 128 bytes.
+    string value = 2;
+  }
+
+  // The resource name of the product.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  //
+  // This field is ignored when creating a product.
+  string name = 1;
+
+  // The user-provided name for this Product. Must not be empty. Must be at most
+  // 4096 characters long.
+  string display_name = 2;
+
+  // User-provided metadata to be stored with this product. Must be at most 4096
+  // characters long.
+  string description = 3;
+
+  // The category for the product identified by the reference image. This should
+  // be either "homegoods" or "apparel".
+  //
+  // This field is immutable.
+  string product_category = 4;
+
+  // Key-value pairs that can be attached to a product. At query time,
+  // constraints can be specified based on the product_labels.
+  //
+  // Note that integer values can be provided as strings, e.g. "1199". Only
+  // strings with integer values can match a range-based restriction which is
+  // to be supported soon.
+  //
+  // Multiple values can be assigned to the same key. One product may have up to
+  // 100 product_labels.
+  repeated KeyValue product_labels = 5;
+}
+
+// A ProductSet contains Products. A ProductSet can contain a maximum of 1
+// million reference images. If the limit is exceeded, periodic indexing will
+// fail.
+message ProductSet {
+  // The resource name of the ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`.
+  //
+  // This field is ignored when creating a ProductSet.
+  string name = 1;
+
+  // The user-provided name for this ProductSet. Must not be empty. Must be at
+  // most 4096 characters long.
+  string display_name = 2;
+
+  // Output only. The time at which this ProductSet was last indexed. Query
+  // results will reflect all updates before this time. If this ProductSet has
+  // never been indexed, this field is 0.
+  //
+  // This field is ignored when creating a ProductSet.
+  google.protobuf.Timestamp index_time = 3;
+
+  // Output only. If there was an error with indexing the product set, the field
+  // is populated.
+  //
+  // This field is ignored when creating a ProductSet.
+  google.rpc.Status index_error = 4;
+}
+
+// A `ReferenceImage` represents a product image and its associated metadata,
+// such as bounding boxes.
+message ReferenceImage {
+  // The resource name of the reference image.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`.
+  //
+  // This field is ignored when creating a reference image.
+  string name = 1;
+
+  // The Google Cloud Storage URI of the reference image.
+  //
+  // The URI must start with `gs://`.
+  //
+  // Required.
+  string uri = 2;
+
+  // Bounding polygons around the areas of interest in the reference image.
+  // Optional. If this field is empty, the system will try to detect regions of
+  // interest. At most 10 bounding polygons will be used.
+  //
+  // The provided shape is converted into a non-rotated rectangle. Once
+  // converted, the small edge of the rectangle must be greater than or equal
+  // to 300 pixels. The aspect ratio must be 1:4 or less (i.e. 1:3 is ok; 1:5
+  // is not).
+  repeated BoundingPoly bounding_polys = 3;
+}
+
+// Request message for the `CreateProduct` method.
+message CreateProductRequest {
+  // The project in which the Product should be created.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The product to create.
+  Product product = 2;
+
+  // A user-supplied resource id for this Product. If set, the server will
+  // attempt to use this value as the resource id. If it is already in use, an
+  // error is returned with code ALREADY_EXISTS. Must be at most 128 characters
+  // long. It cannot contain the character `/`.
+  string product_id = 3;
+}
+
+// Request message for the `ListProducts` method.
+message ListProductsRequest {
+  // The project OR ProductSet from which Products should be listed.
+  //
+  // Format:
+  // `projects/PROJECT_ID/locations/LOC_ID`
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProducts` method.
+message ListProductsResponse {
+  // List of products.
+  repeated Product products = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// Request message for the `GetProduct` method.
+message GetProductRequest {
+  // Resource name of the Product to get.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string name = 1;
+}
+
+// Request message for the `UpdateProduct` method.
+message UpdateProductRequest {
+  // The Product resource which replaces the one on the server.
+  // product.name is immutable.
+  Product product = 1;
+
+  // The [FieldMask][google.protobuf.FieldMask] that specifies which fields
+  // to update.
+  // If update_mask isn't specified, all mutable fields are to be updated.
+  // Valid mask paths include `product_labels`, `display_name` and
+  // `description`.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for the `DeleteProduct` method.
+message DeleteProductRequest {
+  // Resource name of product to delete.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string name = 1;
+}
+
+// Request message for the `CreateProductSet` method.
+message CreateProductSetRequest {
+  // The project in which the ProductSet should be created.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The ProductSet to create.
+  ProductSet product_set = 2;
+
+  // A user-supplied resource id for this ProductSet. If set, the server will
+  // attempt to use this value as the resource id. If it is already in use, an
+  // error is returned with code ALREADY_EXISTS. Must be at most 128 characters
+  // long. It cannot contain the character `/`.
+  string product_set_id = 3;
+}
+
+// Request message for the `ListProductSets` method.
+message ListProductSetsRequest {
+  // The project from which ProductSets should be listed.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProductSets` method.
+message ListProductSetsResponse {
+  // List of ProductSets.
+  repeated ProductSet product_sets = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// Request message for the `GetProductSet` method.
+message GetProductSetRequest {
+  // Resource name of the ProductSet to get.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOG_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+}
+
+// Request message for the `UpdateProductSet` method.
+message UpdateProductSetRequest {
+  // The ProductSet resource which replaces the one on the server.
+  ProductSet product_set = 1;
+
+  // The [FieldMask][google.protobuf.FieldMask] that specifies which fields to
+  // update.
+  // If update_mask isn't specified, all mutable fields are to be updated.
+  // Valid mask path is `display_name`.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for the `DeleteProductSet` method.
+message DeleteProductSetRequest {
+  // Resource name of the ProductSet to delete.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+}
+
+// Request message for the `CreateReferenceImage` method.
+message CreateReferenceImageRequest {
+  // Resource name of the product in which to create the reference image.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  string parent = 1;
+
+  // The reference image to create.
+  // If an image ID is specified, it is ignored.
+  ReferenceImage reference_image = 2;
+
+  // A user-supplied resource id for the ReferenceImage to be added. If set,
+  // the server will attempt to use this value as the resource id. If it is
+  // already in use, an error is returned with code ALREADY_EXISTS. Must be at
+  // most 128 characters long. It cannot contain the character `/`.
+  string reference_image_id = 3;
+}
+
+// Request message for the `ListReferenceImages` method.
+message ListReferenceImagesRequest {
+  // Resource name of the product containing the reference images.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // A token identifying a page of results to be returned. This is the value
+  // of `nextPageToken` returned in a previous reference image list request.
+  //
+  // Defaults to the first page if not specified.
+  string page_token = 3;
+}
+
+// Response message for the `ListReferenceImages` method.
+message ListReferenceImagesResponse {
+  // The list of reference images.
+  repeated ReferenceImage reference_images = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string next_page_token = 3;
+}
+
+// Request message for the `GetReferenceImage` method.
+message GetReferenceImageRequest {
+  // The resource name of the ReferenceImage to get.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`.
+  string name = 1;
+}
+
+// Request message for the `DeleteReferenceImage` method.
+message DeleteReferenceImageRequest {
+  // The resource name of the reference image to delete.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`
+  string name = 1;
+}
+
+// Request message for the `AddProductToProductSet` method.
+message AddProductToProductSetRequest {
+  // The resource name for the ProductSet to modify.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The resource name for the Product to be added to this ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string product = 2;
+}
+
+// Request message for the `RemoveProductFromProductSet` method.
+message RemoveProductFromProductSetRequest {
+  // The resource name for the ProductSet to modify.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The resource name for the Product to be removed from this ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string product = 2;
+}
+
+// Request message for the `ListProductsInProductSet` method.
+message ListProductsInProductSetRequest {
+  // The ProductSet resource for which to retrieve Products.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProductsInProductSet` method.
+message ListProductsInProductSetResponse {
+  // The list of Products.
+  repeated Product products = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// The Google Cloud Storage location for a csv file which preserves a list of
+// ImportProductSetRequests in each line.
+message ImportProductSetsGcsSource {
+  // The Google Cloud Storage URI of the input csv file.
+  //
+  // The URI must start with gs://
+  //
+  // The format of the input csv file should be one image per line.
+  // In each line, there are 6 columns.
+  // 1. image_uri
+  // 2, image_id
+  // 3. product_set_id
+  // 4. product_id
+  // 5, product_category
+  // 6, product_display_name
+  // 7, labels
+  // 8. bounding_poly
+  //
+  // Columns 1, 3, 4, and 5 are required, other columns are optional. A new
+  // ProductSet/Product with the same id will be created on the fly
+  // if the ProductSet/Product specified by product_set_id/product_id does not
+  // exist.
+  //
+  // The image_id field is optional but has to be unique if provided. If it is
+  // empty, we will automatically assign an unique id to the image.
+  //
+  // The product_display_name field is optional. If it is empty, a space (" ")
+  // is used as the place holder for the product display_name, which can
+  // be updated later through the realtime API.
+  //
+  // If the Product with product_id already exists, the fields
+  // product_display_name, product_category and labels are ignored.
+  //
+  // If a Product doesn't exist and needs to be created on the fly, the
+  // product_display_name field refers to [Product.display_name][google.cloud.vision.v1p3beta1.Product.display_name], the
+  // product_category field refers to [Product.product_category][google.cloud.vision.v1p3beta1.Product.product_category], and the
+  // labels field refers to [Product.labels][].
+  //
+  // Labels (optional) should be a line containing a list of comma-separated
+  // key-value pairs, with the format
+  //     "key_1=value_1,key_2=value_2,...,key_n=value_n".
+  //
+  // The bounding_poly (optional) field is used to identify one region of
+  // interest from the image in the same manner as CreateReferenceImage. If no
+  // bounding_poly is specified, the system will try to detect regions of
+  // interest automatically.
+  //
+  // Note that the pipeline will resize the image if the image resolution is too
+  // large to process (above 20MP).
+  //
+  // Also note that at most one bounding_poly is allowed per line. If the image
+  // contains multiple regions of interest, the csv should contain one line per
+  // region of interest.
+  //
+  // The bounding_poly column should contain an even number of comma-separated
+  // numbers, with the format "p1_x,p1_y,p2_x,p2_y,...,pn_x,pn_y". Nonnegative
+  // integers should be used for absolute bounding polygons, and float values
+  // in [0, 1] should be used for normalized bounding polygons.
+  string csv_file_uri = 1;
+}
+
+// The input content for the `ImportProductSets` method.
+message ImportProductSetsInputConfig {
+  // The source of the input.
+  oneof source {
+    // The Google Cloud Storage location for a csv file which preserves a list
+    // of ImportProductSetRequests in each line.
+    ImportProductSetsGcsSource gcs_source = 1;
+  }
+}
+
+// Request message for the `ImportProductSets` method.
+message ImportProductSetsRequest {
+  // The project in which the ProductSets should be imported.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The input content for the list of requests.
+  ImportProductSetsInputConfig input_config = 2;
+}
+
+// Response message for the `ImportProductSets` method.
+//
+// This message is returned by the
+// [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] method in the returned
+// [google.longrunning.Operation.response][google.longrunning.Operation.response] field.
+message ImportProductSetsResponse {
+  // The list of reference_images that are imported successfully.
+  repeated ReferenceImage reference_images = 1;
+
+  // The rpc status for each ImportProductSet request, including both successes
+  // and errors.
+  //
+  // The number of statuses here matches the number of lines in the csv file,
+  // and statuses[i] stores the success or failure status of processing the i-th
+  // line of the csv, starting from line 0.
+  repeated google.rpc.Status statuses = 2;
+}
+
+// Metadata for the batch operations such as the current state.
+//
+// This is included in the `metadata` field of the `Operation` returned by the
+// `GetOperation` call of the `google::longrunning::Operations` service.
+message BatchOperationMetadata {
+  // Enumerates the possible states that the batch request can be in.
+  enum State {
+    // Invalid.
+    STATE_UNSPECIFIED = 0;
+
+    // Request is actively being processed.
+    PROCESSING = 1;
+
+    // The request is done and at least one item has been successfully
+    // processed.
+    SUCCESSFUL = 2;
+
+    // The request is done and no item has been successfully processed.
+    FAILED = 3;
+
+    // The request is done after the longrunning.Operations.CancelOperation has
+    // been called by the user.  Any records that were processed before the
+    // cancel command are output as specified in the request.
+    CANCELLED = 4;
+  }
+
+  // The current state of the batch operation.
+  State state = 1;
+
+  // The time when the batch request was submitted to the server.
+  google.protobuf.Timestamp submit_time = 2;
+
+  // The time when the batch request is finished and
+  // [google.longrunning.Operation.done][google.longrunning.Operation.done] is set to true.
+  google.protobuf.Timestamp end_time = 3;
+}
diff --git a/vision/google/cloud/vision_v1/proto/text_annotation.proto b/vision/google/cloud/vision_v1/proto/text_annotation.proto
new file mode 100644
index 000000000000..928e6e88bb07
--- /dev/null
+++ b/vision/google/cloud/vision_v1/proto/text_annotation.proto
@@ -0,0 +1,252 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p1beta1/geometry.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "TextAnnotationProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// TextAnnotation contains a structured representation of OCR extracted text.
+// The hierarchy of an OCR extracted text structure is like this:
+//     TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol
+// Each structural component, starting from Page, may further have their own
+// properties. Properties describe detected languages, breaks etc.. Please refer
+// to the
+// [TextAnnotation.TextProperty][google.cloud.vision.v1p1beta1.TextAnnotation.TextProperty]
+// message definition below for more detail.
+message TextAnnotation {
+  // Detected language for a structural component.
+  message DetectedLanguage {
+    // The BCP-47 language code, such as "en-US" or "sr-Latn". For more
+    // information, see
+    // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+    string language_code = 1;
+
+    // Confidence of detected language. Range [0, 1].
+    float confidence = 2;
+  }
+
+  // Detected start or end of a structural component.
+  message DetectedBreak {
+    // Enum to denote the type of break found. New line, space etc.
+    enum BreakType {
+      // Unknown break label type.
+      UNKNOWN = 0;
+
+      // Regular space.
+      SPACE = 1;
+
+      // Sure space (very wide).
+      SURE_SPACE = 2;
+
+      // Line-wrapping break.
+      EOL_SURE_SPACE = 3;
+
+      // End-line hyphen that is not present in text; does not co-occur with
+      // `SPACE`, `LEADER_SPACE`, or `LINE_BREAK`.
+      HYPHEN = 4;
+
+      // Line break that ends a paragraph.
+      LINE_BREAK = 5;
+    }
+
+    // Detected break type.
+    BreakType type = 1;
+
+    // True if break prepends the element.
+    bool is_prefix = 2;
+  }
+
+  // Additional information detected on the structural component.
+  message TextProperty {
+    // A list of detected languages together with confidence.
+    repeated DetectedLanguage detected_languages = 1;
+
+    // Detected start or end of a text segment.
+    DetectedBreak detected_break = 2;
+  }
+
+  // List of pages detected by OCR.
+  repeated Page pages = 1;
+
+  // UTF-8 text detected on the pages.
+  string text = 2;
+}
+
+// Detected page from OCR.
+message Page {
+  // Additional information detected on the page.
+  TextAnnotation.TextProperty property = 1;
+
+  // Page width in pixels.
+  int32 width = 2;
+
+  // Page height in pixels.
+  int32 height = 3;
+
+  // List of blocks of text, images etc on this page.
+  repeated Block blocks = 4;
+
+  // Confidence of the OCR results on the page. Range [0, 1].
+  float confidence = 5;
+}
+
+// Logical element on the page.
+message Block {
+  // Type of a block (text, image etc) as identified by OCR.
+  enum BlockType {
+    // Unknown block type.
+    UNKNOWN = 0;
+
+    // Regular text block.
+    TEXT = 1;
+
+    // Table block.
+    TABLE = 2;
+
+    // Image block.
+    PICTURE = 3;
+
+    // Horizontal/vertical line box.
+    RULER = 4;
+
+    // Barcode block.
+    BARCODE = 5;
+  }
+
+  // Additional information detected for the block.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the block.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of paragraphs in this block (if this blocks is of type text).
+  repeated Paragraph paragraphs = 3;
+
+  // Detected block type (text, image etc) for this block.
+  BlockType block_type = 4;
+
+  // Confidence of the OCR results on the block. Range [0, 1].
+  float confidence = 5;
+}
+
+// Structural unit of text representing a number of words in certain order.
+message Paragraph {
+  // Additional information detected for the paragraph.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the paragraph.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of words in this paragraph.
+  repeated Word words = 3;
+
+  // Confidence of the OCR results for the paragraph. Range [0, 1].
+  float confidence = 4;
+}
+
+// A word representation.
+message Word {
+  // Additional information detected for the word.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the word.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of symbols in the word.
+  // The order of the symbols follows the natural reading order.
+  repeated Symbol symbols = 3;
+
+  // Confidence of the OCR results for the word. Range [0, 1].
+  float confidence = 4;
+}
+
+// A single symbol representation.
+message Symbol {
+  // Additional information detected for the symbol.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the symbol.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // The actual UTF-8 representation of the symbol.
+  string text = 3;
+
+  // Confidence of the OCR results for the symbol. Range [0, 1].
+  float confidence = 4;
+}
diff --git a/vision/google/cloud/vision_v1/proto/web_detection.proto b/vision/google/cloud/vision_v1/proto/web_detection.proto
new file mode 100644
index 000000000000..28249cbdec22
--- /dev/null
+++ b/vision/google/cloud/vision_v1/proto/web_detection.proto
@@ -0,0 +1,104 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "WebDetectionProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// Relevant information for the image from the Internet.
+message WebDetection {
+  // Entity deduced from similar images on the Internet.
+  message WebEntity {
+    // Opaque entity ID.
+    string entity_id = 1;
+
+    // Overall relevancy score for the entity.
+    // Not normalized and not comparable across different image queries.
+    float score = 2;
+
+    // Canonical description of the entity, in English.
+    string description = 3;
+  }
+
+  // Metadata for online images.
+  message WebImage {
+    // The result image URL.
+    string url = 1;
+
+    // (Deprecated) Overall relevancy score for the image.
+    float score = 2;
+  }
+
+  // Metadata for web pages.
+  message WebPage {
+    // The result web page URL.
+    string url = 1;
+
+    // (Deprecated) Overall relevancy score for the web page.
+    float score = 2;
+
+    // Title for the web page, may contain HTML markups.
+    string page_title = 3;
+
+    // Fully matching images on the page.
+    // Can include resized copies of the query image.
+    repeated WebImage full_matching_images = 4;
+
+    // Partial matching images on the page.
+    // Those images are similar enough to share some key-point features. For
+    // example an original image will likely have partial matching for its
+    // crops.
+    repeated WebImage partial_matching_images = 5;
+  }
+
+  // Label to provide extra metadata for the web detection.
+  message WebLabel {
+    // Label for extra metadata.
+    string label = 1;
+
+    // The BCP-47 language code for `label`, such as "en-US" or "sr-Latn".
+    // For more information, see
+    // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+    string language_code = 2;
+  }
+
+  // Deduced entities from similar images on the Internet.
+  repeated WebEntity web_entities = 1;
+
+  // Fully matching images from the Internet.
+  // Can include resized copies of the query image.
+  repeated WebImage full_matching_images = 2;
+
+  // Partial matching images from the Internet.
+  // Those images are similar enough to share some key-point features. For
+  // example an original image will likely have partial matching for its crops.
+  repeated WebImage partial_matching_images = 3;
+
+  // Web pages containing the matching images from the Internet.
+  repeated WebPage pages_with_matching_images = 4;
+
+  // The visually similar image results.
+  repeated WebImage visually_similar_images = 6;
+
+  // Best guess text labels for the request image.
+  repeated WebLabel best_guess_labels = 8;
+}
diff --git a/vision/google/cloud/vision_v1p1beta1/proto/geometry.proto b/vision/google/cloud/vision_v1p1beta1/proto/geometry.proto
new file mode 100644
index 000000000000..6d46d9c342ec
--- /dev/null
+++ b/vision/google/cloud/vision_v1p1beta1/proto/geometry.proto
@@ -0,0 +1,53 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "GeometryProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// A vertex represents a 2D point in the image.
+// NOTE: the vertex coordinates are in the same scale as the original image.
+message Vertex {
+  // X coordinate.
+  int32 x = 1;
+
+  // Y coordinate.
+  int32 y = 2;
+}
+
+// A bounding polygon for the detected image annotation.
+message BoundingPoly {
+  // The bounding polygon vertices.
+  repeated Vertex vertices = 1;
+}
+
+// A 3D position in the image, used primarily for Face detection landmarks.
+// A valid Position must have both x and y coordinates.
+// The position coordinates are in the same scale as the original image.
+message Position {
+  // X coordinate.
+  float x = 1;
+
+  // Y coordinate.
+  float y = 2;
+
+  // Z coordinate (or depth).
+  float z = 3;
+}
diff --git a/vision/google/cloud/vision_v1p1beta1/proto/image_annotator.proto b/vision/google/cloud/vision_v1p1beta1/proto/image_annotator.proto
new file mode 100644
index 000000000000..73b8db853aad
--- /dev/null
+++ b/vision/google/cloud/vision_v1p1beta1/proto/image_annotator.proto
@@ -0,0 +1,591 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p1beta1/geometry.proto";
+import "google/cloud/vision/v1p1beta1/text_annotation.proto";
+import "google/cloud/vision/v1p1beta1/web_detection.proto";
+import "google/rpc/status.proto";
+import "google/type/color.proto";
+import "google/type/latlng.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ImageAnnotatorProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// Service that performs Google Cloud Vision API detection tasks over client
+// images, such as face, landmark, logo, label, and text detection. The
+// ImageAnnotator service returns detected entities from the images.
+service ImageAnnotator {
+  // Run image detection and annotation for a batch of images.
+  rpc BatchAnnotateImages(BatchAnnotateImagesRequest)
+      returns (BatchAnnotateImagesResponse) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/images:annotate"
+      body: "*"
+    };
+  }
+}
+
+// Users describe the type of Google Cloud Vision API tasks to perform over
+// images by using *Feature*s. Each Feature indicates a type of image
+// detection task to perform. Features encode the Cloud Vision API
+// vertical to operate on and the number of top-scoring results to return.
+message Feature {
+  // Type of image feature.
+  enum Type {
+    // Unspecified feature type.
+    TYPE_UNSPECIFIED = 0;
+
+    // Run face detection.
+    FACE_DETECTION = 1;
+
+    // Run landmark detection.
+    LANDMARK_DETECTION = 2;
+
+    // Run logo detection.
+    LOGO_DETECTION = 3;
+
+    // Run label detection.
+    LABEL_DETECTION = 4;
+
+    // Run OCR.
+    TEXT_DETECTION = 5;
+
+    // Run dense text document OCR. Takes precedence when both
+    // DOCUMENT_TEXT_DETECTION and TEXT_DETECTION are present.
+    DOCUMENT_TEXT_DETECTION = 11;
+
+    // Run computer vision models to compute image safe-search properties.
+    SAFE_SEARCH_DETECTION = 6;
+
+    // Compute a set of image properties, such as the image's dominant colors.
+    IMAGE_PROPERTIES = 7;
+
+    // Run crop hints.
+    CROP_HINTS = 9;
+
+    // Run web detection.
+    WEB_DETECTION = 10;
+  }
+
+  // The feature type.
+  Type type = 1;
+
+  // Maximum number of results of this type.
+  int32 max_results = 2;
+
+  // Model to use for the feature.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 3;
+}
+
+// External image source (Google Cloud Storage image location).
+message ImageSource {
+  // NOTE: For new code `image_uri` below is preferred.
+  // Google Cloud Storage image URI, which must be in the following form:
+  // `gs://bucket_name/object_name` (for details, see
+  // [Google Cloud Storage Request
+  // URIs](https://cloud.google.com/storage/docs/reference-uris)).
+  // NOTE: Cloud Storage object versioning is not supported.
+  string gcs_image_uri = 1;
+
+  // Image URI which supports:
+  // 1) Google Cloud Storage image URI, which must be in the following form:
+  // `gs://bucket_name/object_name` (for details, see
+  // [Google Cloud Storage Request
+  // URIs](https://cloud.google.com/storage/docs/reference-uris)).
+  // NOTE: Cloud Storage object versioning is not supported.
+  // 2) Publicly accessible image HTTP/HTTPS URL.
+  // This is preferred over the legacy `gcs_image_uri` above. When both
+  // `gcs_image_uri` and `image_uri` are specified, `image_uri` takes
+  // precedence.
+  string image_uri = 2;
+}
+
+// Client image to perform Google Cloud Vision API tasks over.
+message Image {
+  // Image content, represented as a stream of bytes.
+  // Note: as with all `bytes` fields, protobuffers use a pure binary
+  // representation, whereas JSON representations use base64.
+  bytes content = 1;
+
+  // Google Cloud Storage image location. If both `content` and `source`
+  // are provided for an image, `content` takes precedence and is
+  // used to perform the image annotation request.
+  ImageSource source = 2;
+}
+
+// A face annotation object contains the results of face detection.
+message FaceAnnotation {
+  // A face-specific landmark (for example, a face feature).
+  message Landmark {
+    // Face landmark (feature) type.
+    // Left and right are defined from the vantage of the viewer of the image
+    // without considering mirror projections typical of photos. So, `LEFT_EYE`,
+    // typically, is the person's right eye.
+    enum Type {
+      // Unknown face landmark detected. Should not be filled.
+      UNKNOWN_LANDMARK = 0;
+
+      // Left eye.
+      LEFT_EYE = 1;
+
+      // Right eye.
+      RIGHT_EYE = 2;
+
+      // Left of left eyebrow.
+      LEFT_OF_LEFT_EYEBROW = 3;
+
+      // Right of left eyebrow.
+      RIGHT_OF_LEFT_EYEBROW = 4;
+
+      // Left of right eyebrow.
+      LEFT_OF_RIGHT_EYEBROW = 5;
+
+      // Right of right eyebrow.
+      RIGHT_OF_RIGHT_EYEBROW = 6;
+
+      // Midpoint between eyes.
+      MIDPOINT_BETWEEN_EYES = 7;
+
+      // Nose tip.
+      NOSE_TIP = 8;
+
+      // Upper lip.
+      UPPER_LIP = 9;
+
+      // Lower lip.
+      LOWER_LIP = 10;
+
+      // Mouth left.
+      MOUTH_LEFT = 11;
+
+      // Mouth right.
+      MOUTH_RIGHT = 12;
+
+      // Mouth center.
+      MOUTH_CENTER = 13;
+
+      // Nose, bottom right.
+      NOSE_BOTTOM_RIGHT = 14;
+
+      // Nose, bottom left.
+      NOSE_BOTTOM_LEFT = 15;
+
+      // Nose, bottom center.
+      NOSE_BOTTOM_CENTER = 16;
+
+      // Left eye, top boundary.
+      LEFT_EYE_TOP_BOUNDARY = 17;
+
+      // Left eye, right corner.
+      LEFT_EYE_RIGHT_CORNER = 18;
+
+      // Left eye, bottom boundary.
+      LEFT_EYE_BOTTOM_BOUNDARY = 19;
+
+      // Left eye, left corner.
+      LEFT_EYE_LEFT_CORNER = 20;
+
+      // Right eye, top boundary.
+      RIGHT_EYE_TOP_BOUNDARY = 21;
+
+      // Right eye, right corner.
+      RIGHT_EYE_RIGHT_CORNER = 22;
+
+      // Right eye, bottom boundary.
+      RIGHT_EYE_BOTTOM_BOUNDARY = 23;
+
+      // Right eye, left corner.
+      RIGHT_EYE_LEFT_CORNER = 24;
+
+      // Left eyebrow, upper midpoint.
+      LEFT_EYEBROW_UPPER_MIDPOINT = 25;
+
+      // Right eyebrow, upper midpoint.
+      RIGHT_EYEBROW_UPPER_MIDPOINT = 26;
+
+      // Left ear tragion.
+      LEFT_EAR_TRAGION = 27;
+
+      // Right ear tragion.
+      RIGHT_EAR_TRAGION = 28;
+
+      // Left eye pupil.
+      LEFT_EYE_PUPIL = 29;
+
+      // Right eye pupil.
+      RIGHT_EYE_PUPIL = 30;
+
+      // Forehead glabella.
+      FOREHEAD_GLABELLA = 31;
+
+      // Chin gnathion.
+      CHIN_GNATHION = 32;
+
+      // Chin left gonion.
+      CHIN_LEFT_GONION = 33;
+
+      // Chin right gonion.
+      CHIN_RIGHT_GONION = 34;
+    }
+
+    // Face landmark type.
+    Type type = 3;
+
+    // Face landmark position.
+    Position position = 4;
+  }
+
+  // The bounding polygon around the face. The coordinates of the bounding box
+  // are in the original image's scale, as returned in `ImageParams`.
+  // The bounding box is computed to "frame" the face in accordance with human
+  // expectations. It is based on the landmarker results.
+  // Note that one or more x and/or y coordinates may not be generated in the
+  // `BoundingPoly` (the polygon will be unbounded) if only a partial face
+  // appears in the image to be annotated.
+  BoundingPoly bounding_poly = 1;
+
+  // The `fd_bounding_poly` bounding polygon is tighter than the
+  // `boundingPoly`, and encloses only the skin part of the face. Typically, it
+  // is used to eliminate the face from any image analysis that detects the
+  // "amount of skin" visible in an image. It is not based on the
+  // landmarker results, only on the initial face detection, hence
+  // the <code>fd</code> (face detection) prefix.
+  BoundingPoly fd_bounding_poly = 2;
+
+  // Detected face landmarks.
+  repeated Landmark landmarks = 3;
+
+  // Roll angle, which indicates the amount of clockwise/anti-clockwise rotation
+  // of the face relative to the image vertical about the axis perpendicular to
+  // the face. Range [-180,180].
+  float roll_angle = 4;
+
+  // Yaw angle, which indicates the leftward/rightward angle that the face is
+  // pointing relative to the vertical plane perpendicular to the image. Range
+  // [-180,180].
+  float pan_angle = 5;
+
+  // Pitch angle, which indicates the upwards/downwards angle that the face is
+  // pointing relative to the image's horizontal plane. Range [-180,180].
+  float tilt_angle = 6;
+
+  // Detection confidence. Range [0, 1].
+  float detection_confidence = 7;
+
+  // Face landmarking confidence. Range [0, 1].
+  float landmarking_confidence = 8;
+
+  // Joy likelihood.
+  Likelihood joy_likelihood = 9;
+
+  // Sorrow likelihood.
+  Likelihood sorrow_likelihood = 10;
+
+  // Anger likelihood.
+  Likelihood anger_likelihood = 11;
+
+  // Surprise likelihood.
+  Likelihood surprise_likelihood = 12;
+
+  // Under-exposed likelihood.
+  Likelihood under_exposed_likelihood = 13;
+
+  // Blurred likelihood.
+  Likelihood blurred_likelihood = 14;
+
+  // Headwear likelihood.
+  Likelihood headwear_likelihood = 15;
+}
+
+// Detected entity location information.
+message LocationInfo {
+  // lat/long location coordinates.
+  google.type.LatLng lat_lng = 1;
+}
+
+// A `Property` consists of a user-supplied name/value pair.
+message Property {
+  // Name of the property.
+  string name = 1;
+
+  // Value of the property.
+  string value = 2;
+
+  // Value of numeric properties.
+  uint64 uint64_value = 3;
+}
+
+// Set of detected entity features.
+message EntityAnnotation {
+  // Opaque entity ID. Some IDs may be available in
+  // [Google Knowledge Graph Search API](https://developers.google.com/knowledge-graph/).
+  string mid = 1;
+
+  // The language code for the locale in which the entity textual
+  // `description` is expressed.
+  string locale = 2;
+
+  // Entity textual description, expressed in its `locale` language.
+  string description = 3;
+
+  // Overall score of the result. Range [0, 1].
+  float score = 4;
+
+  // The accuracy of the entity detection in an image.
+  // For example, for an image in which the "Eiffel Tower" entity is detected,
+  // this field represents the confidence that there is a tower in the query
+  // image. Range [0, 1].
+  float confidence = 5;
+
+  // The relevancy of the ICA (Image Content Annotation) label to the
+  // image. For example, the relevancy of "tower" is likely higher to an image
+  // containing the detected "Eiffel Tower" than to an image containing a
+  // detected distant towering building, even though the confidence that
+  // there is a tower in each image may be the same. Range [0, 1].
+  float topicality = 6;
+
+  // Image region to which this entity belongs. Not produced
+  // for `LABEL_DETECTION` features.
+  BoundingPoly bounding_poly = 7;
+
+  // The location information for the detected entity. Multiple
+  // `LocationInfo` elements can be present because one location may
+  // indicate the location of the scene in the image, and another location
+  // may indicate the location of the place where the image was taken.
+  // Location information is usually present for landmarks.
+  repeated LocationInfo locations = 8;
+
+  // Some entities may have optional user-supplied `Property` (name/value)
+  // fields, such a score or string that qualifies the entity.
+  repeated Property properties = 9;
+}
+
+// Set of features pertaining to the image, computed by computer vision
+// methods over safe-search verticals (for example, adult, spoof, medical,
+// violence).
+message SafeSearchAnnotation {
+  // Represents the adult content likelihood for the image. Adult content may
+  // contain elements such as nudity, pornographic images or cartoons, or
+  // sexual activities.
+  Likelihood adult = 1;
+
+  // Spoof likelihood. The likelihood that an modification
+  // was made to the image's canonical version to make it appear
+  // funny or offensive.
+  Likelihood spoof = 2;
+
+  // Likelihood that this is a medical image.
+  Likelihood medical = 3;
+
+  // Likelihood that this image contains violent content.
+  Likelihood violence = 4;
+
+  // Likelihood that the request image contains racy content. Racy content may
+  // include (but is not limited to) skimpy or sheer clothing, strategically
+  // covered nudity, lewd or provocative poses, or close-ups of sensitive
+  // body areas.
+  Likelihood racy = 9;
+}
+
+// Rectangle determined by min and max `LatLng` pairs.
+message LatLongRect {
+  // Min lat/long pair.
+  google.type.LatLng min_lat_lng = 1;
+
+  // Max lat/long pair.
+  google.type.LatLng max_lat_lng = 2;
+}
+
+// Color information consists of RGB channels, score, and the fraction of
+// the image that the color occupies in the image.
+message ColorInfo {
+  // RGB components of the color.
+  google.type.Color color = 1;
+
+  // Image-specific score for this color. Value in range [0, 1].
+  float score = 2;
+
+  // The fraction of pixels the color occupies in the image.
+  // Value in range [0, 1].
+  float pixel_fraction = 3;
+}
+
+// Set of dominant colors and their corresponding scores.
+message DominantColorsAnnotation {
+  // RGB color values with their score and pixel fraction.
+  repeated ColorInfo colors = 1;
+}
+
+// Stores image properties, such as dominant colors.
+message ImageProperties {
+  // If present, dominant colors completed successfully.
+  DominantColorsAnnotation dominant_colors = 1;
+}
+
+// Single crop hint that is used to generate a new crop when serving an image.
+message CropHint {
+  // The bounding polygon for the crop region. The coordinates of the bounding
+  // box are in the original image's scale, as returned in `ImageParams`.
+  BoundingPoly bounding_poly = 1;
+
+  // Confidence of this being a salient region.  Range [0, 1].
+  float confidence = 2;
+
+  // Fraction of importance of this salient region with respect to the original
+  // image.
+  float importance_fraction = 3;
+}
+
+// Set of crop hints that are used to generate new crops when serving images.
+message CropHintsAnnotation {
+  // Crop hint results.
+  repeated CropHint crop_hints = 1;
+}
+
+// Parameters for crop hints annotation request.
+message CropHintsParams {
+  // Aspect ratios in floats, representing the ratio of the width to the height
+  // of the image. For example, if the desired aspect ratio is 4/3, the
+  // corresponding float value should be 1.33333.  If not specified, the
+  // best possible crop is returned. The number of provided aspect ratios is
+  // limited to a maximum of 16; any aspect ratios provided after the 16th are
+  // ignored.
+  repeated float aspect_ratios = 1;
+}
+
+// Parameters for web detection request.
+message WebDetectionParams {
+  // Whether to include results derived from the geo information in the image.
+  bool include_geo_results = 2;
+}
+
+// Image context and/or feature-specific parameters.
+message ImageContext {
+  // lat/long rectangle that specifies the location of the image.
+  LatLongRect lat_long_rect = 1;
+
+  // List of languages to use for TEXT_DETECTION. In most cases, an empty value
+  // yields the best results since it enables automatic language detection. For
+  // languages based on the Latin alphabet, setting `language_hints` is not
+  // needed. In rare cases, when the language of the text in the image is known,
+  // setting a hint will help get better results (although it will be a
+  // significant hindrance if the hint is wrong). Text detection returns an
+  // error if one or more of the specified languages is not one of the
+  // [supported languages](/vision/docs/languages).
+  repeated string language_hints = 2;
+
+  // Parameters for crop hints annotation request.
+  CropHintsParams crop_hints_params = 4;
+
+  // Parameters for web detection.
+  WebDetectionParams web_detection_params = 6;
+}
+
+// Request for performing Google Cloud Vision API tasks over a user-provided
+// image, with user-requested features.
+message AnnotateImageRequest {
+  // The image to be processed.
+  Image image = 1;
+
+  // Requested features.
+  repeated Feature features = 2;
+
+  // Additional context that may accompany the image.
+  ImageContext image_context = 3;
+}
+
+// Response to an image annotation request.
+message AnnotateImageResponse {
+  // If present, face detection has completed successfully.
+  repeated FaceAnnotation face_annotations = 1;
+
+  // If present, landmark detection has completed successfully.
+  repeated EntityAnnotation landmark_annotations = 2;
+
+  // If present, logo detection has completed successfully.
+  repeated EntityAnnotation logo_annotations = 3;
+
+  // If present, label detection has completed successfully.
+  repeated EntityAnnotation label_annotations = 4;
+
+  // If present, text (OCR) detection has completed successfully.
+  repeated EntityAnnotation text_annotations = 5;
+
+  // If present, text (OCR) detection or document (OCR) text detection has
+  // completed successfully.
+  // This annotation provides the structural hierarchy for the OCR detected
+  // text.
+  TextAnnotation full_text_annotation = 12;
+
+  // If present, safe-search annotation has completed successfully.
+  SafeSearchAnnotation safe_search_annotation = 6;
+
+  // If present, image properties were extracted successfully.
+  ImageProperties image_properties_annotation = 8;
+
+  // If present, crop hints have completed successfully.
+  CropHintsAnnotation crop_hints_annotation = 11;
+
+  // If present, web detection has completed successfully.
+  WebDetection web_detection = 13;
+
+  // If set, represents the error message for the operation.
+  // Note that filled-in image annotations are guaranteed to be
+  // correct, even when `error` is set.
+  google.rpc.Status error = 9;
+}
+
+// Multiple image annotation requests are batched into a single service call.
+message BatchAnnotateImagesRequest {
+  // Individual image annotation requests for this batch.
+  repeated AnnotateImageRequest requests = 1;
+}
+
+// Response to a batch image annotation request.
+message BatchAnnotateImagesResponse {
+  // Individual responses to image annotation requests within the batch.
+  repeated AnnotateImageResponse responses = 1;
+}
+
+// A bucketized representation of likelihood, which is intended to give clients
+// highly stable results across model upgrades.
+enum Likelihood {
+  // Unknown likelihood.
+  UNKNOWN = 0;
+
+  // It is very unlikely that the image belongs to the specified vertical.
+  VERY_UNLIKELY = 1;
+
+  // It is unlikely that the image belongs to the specified vertical.
+  UNLIKELY = 2;
+
+  // It is possible that the image belongs to the specified vertical.
+  POSSIBLE = 3;
+
+  // It is likely that the image belongs to the specified vertical.
+  LIKELY = 4;
+
+  // It is very likely that the image belongs to the specified vertical.
+  VERY_LIKELY = 5;
+}
diff --git a/vision/google/cloud/vision_v1p1beta1/proto/product_search.proto b/vision/google/cloud/vision_v1p1beta1/proto/product_search.proto
new file mode 100644
index 000000000000..85e4e0784e1c
--- /dev/null
+++ b/vision/google/cloud/vision_v1p1beta1/proto/product_search.proto
@@ -0,0 +1,161 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p3beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p3beta1/geometry.proto";
+import "google/cloud/vision/v1p3beta1/product_search_service.proto";
+import "google/protobuf/timestamp.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ProductSearchProto";
+option java_package = "com.google.cloud.vision.v1p3beta1";
+
+
+// Parameters for a product search request.
+message ProductSearchParams {
+  // The resource name of the catalog to search.
+  //
+  // Format is: `productSearch/catalogs/CATALOG_NAME`.
+  string catalog_name = 1;
+
+  // The category to search in.
+  // Optional. It is inferred by the system if it is not specified.
+  // [Deprecated] Use `product_category`.
+  ProductSearchCategory category = 2;
+
+  // The product category to search in.
+  // Optional. It is inferred by the system if it is not specified.
+  // Supported values are `bag`, `shoe`, `sunglasses`, `dress`, `outerwear`,
+  // `skirt`, `top`, `shorts`, and `pants`.
+  string product_category = 5;
+
+  // The bounding polygon around the area of interest in the image.
+  // Optional. If it is not specified, system discretion will be applied.
+  // [Deprecated] Use `bounding_poly`.
+  NormalizedBoundingPoly normalized_bounding_poly = 3;
+
+  // The bounding polygon around the area of interest in the image.
+  // Optional. If it is not specified, system discretion will be applied.
+  BoundingPoly bounding_poly = 9;
+
+  // Specifies the verbosity of the  product search results.
+  // Optional. Defaults to `BASIC`.
+  ProductSearchResultsView view = 4;
+
+  // The resource name of a [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] to be searched for similar images.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`.
+  string product_set = 6;
+
+  // The list of product categories to search in. Currently, we only consider
+  // the first category, and either "homegoods" or "apparel" should be
+  // specified.
+  repeated string product_categories = 7;
+
+  // The filtering expression. This can be used to restrict search results based
+  // on Product labels. We currently support an AND of OR of key-value
+  // expressions, where each expression within an OR must have the same key.
+  //
+  // For example, "(color = red OR color = blue) AND brand = Google" is
+  // acceptable, but not "(color = red OR brand = Google)" or "color: red".
+  string filter = 8;
+}
+
+// Results for a product search request.
+message ProductSearchResults {
+  // Information about a product.
+  message ProductInfo {
+    // Product ID.
+    string product_id = 1;
+
+    // The URI of the image which matched the query image.
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    string image_uri = 2;
+
+    // A confidence level on the match, ranging from 0 (no confidence) to
+    // 1 (full confidence).
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    float score = 3;
+  }
+
+  // Information about a product.
+  message Result {
+    // The Product.
+    Product product = 1;
+
+    // A confidence level on the match, ranging from 0 (no confidence) to
+    // 1 (full confidence).
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    float score = 2;
+
+    // The resource name of the image from the product that is the closest match
+    // to the query.
+    string image = 3;
+  }
+
+  // Product category.
+  // [Deprecated] Use `product_category`.
+  ProductSearchCategory category = 1;
+
+  // Product category.
+  // Supported values are `bag` and `shoe`.
+  // [Deprecated] `product_category` is provided in each Product.
+  string product_category = 4;
+
+  // Timestamp of the index which provided these results. Changes made after
+  // this time are not reflected in the current results.
+  google.protobuf.Timestamp index_time = 2;
+
+  // List of detected products.
+  repeated ProductInfo products = 3;
+
+  // List of results, one for each product match.
+  repeated Result results = 5;
+}
+
+// Supported product search categories.
+enum ProductSearchCategory {
+  // Default value used when a category is not specified.
+  PRODUCT_SEARCH_CATEGORY_UNSPECIFIED = 0;
+
+  // Shoes category.
+  SHOES = 1;
+
+  // Bags category.
+  BAGS = 2;
+}
+
+// Specifies the fields to include in product search results.
+enum ProductSearchResultsView {
+  // Product search results contain only `product_category` and `product_id`.
+  // Default value.
+  BASIC = 0;
+
+  // Product search results contain `product_category`, `product_id`,
+  // `image_uri`, and `score`.
+  FULL = 1;
+}
diff --git a/vision/google/cloud/vision_v1p1beta1/proto/product_search_service.proto b/vision/google/cloud/vision_v1p1beta1/proto/product_search_service.proto
new file mode 100644
index 000000000000..90388e36e228
--- /dev/null
+++ b/vision/google/cloud/vision_v1p1beta1/proto/product_search_service.proto
@@ -0,0 +1,825 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p3beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p3beta1/geometry.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ProductSearchServiceProto";
+option java_package = "com.google.cloud.vision.v1p3beta1";
+
+
+// Manages Products and ProductSets of reference images for use in product
+// search. It uses the following resource model:
+//
+// - The API has a collection of [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] resources, named
+// `projects/*/locations/*/productSets/*`, which acts as a way to put different
+// products into groups to limit identification.
+//
+// In parallel,
+//
+// - The API has a collection of [Product][google.cloud.vision.v1p3beta1.Product] resources, named
+//   `projects/*/locations/*/products/*`
+//
+// - Each [Product][google.cloud.vision.v1p3beta1.Product] has a collection of [ReferenceImage][google.cloud.vision.v1p3beta1.ReferenceImage] resources, named
+//   `projects/*/locations/*/products/*/referenceImages/*`
+service ProductSearch {
+  // Creates and returns a new ProductSet resource.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if display_name is missing, or is longer than
+  //   4096 characters.
+  rpc CreateProductSet(CreateProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/productSets"
+      body: "product_set"
+    };
+  }
+
+  // Lists ProductSets in an unspecified order.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100, or less
+  //   than 1.
+  rpc ListProductSets(ListProductSetsRequest) returns (ListProductSetsResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*}/productSets"
+    };
+  }
+
+  // Gets information associated with a ProductSet.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  rpc GetProductSet(GetProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}"
+    };
+  }
+
+  // Makes changes to a ProductSet resource.
+  // Only display_name can be updated currently.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  // * Returns INVALID_ARGUMENT if display_name is present in update_mask but
+  //   missing from the request or longer than 4096 characters.
+  rpc UpdateProductSet(UpdateProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      patch: "/v1p3beta1/{product_set.name=projects/*/locations/*/productSets/*}"
+      body: "product_set"
+    };
+  }
+
+  // Permanently deletes a ProductSet. All Products and ReferenceImages in the
+  // ProductSet will be deleted.
+  //
+  // The actual image files are not deleted from Google Cloud Storage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  rpc DeleteProductSet(DeleteProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}"
+    };
+  }
+
+  // Creates and returns a new product resource.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if display_name is missing or longer than 4096
+  //   characters.
+  // * Returns INVALID_ARGUMENT if description is longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if product_category is missing or invalid.
+  rpc CreateProduct(CreateProductRequest) returns (Product) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/products"
+      body: "product"
+    };
+  }
+
+  // Lists products in an unspecified order.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
+  rpc ListProducts(ListProductsRequest) returns (ListProductsResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*}/products"
+    };
+  }
+
+  // Gets information associated with a Product.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product does not exist.
+  rpc GetProduct(GetProductRequest) returns (Product) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/products/*}"
+    };
+  }
+
+  // Makes changes to a Product resource.
+  // Only display_name, description and labels can be updated right now.
+  //
+  // If labels are updated, the change will not be reflected in queries until
+  // the next index time.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product does not exist.
+  // * Returns INVALID_ARGUMENT if display_name is present in update_mask but is
+  //   missing from the request or longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if description is present in update_mask but is
+  //   longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if product_category is present in update_mask.
+  rpc UpdateProduct(UpdateProductRequest) returns (Product) {
+    option (google.api.http) = {
+      patch: "/v1p3beta1/{product.name=projects/*/locations/*/products/*}"
+      body: "product"
+    };
+  }
+
+  // Permanently deletes a product and its reference images.
+  //
+  // Metadata of the product and all its images will be deleted right away, but
+  // search queries against ProductSets containing the product may still work
+  // until all related caches are refreshed.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the product does not exist.
+  rpc DeleteProduct(DeleteProductRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/products/*}"
+    };
+  }
+
+  // Creates and returns a new ReferenceImage resource.
+  //
+  // The `bounding_poly` field is optional. If `bounding_poly` is not specified,
+  // the system will try to detect regions of interest in the image that are
+  // compatible with the product_category on the parent product. If it is
+  // specified, detection is ALWAYS skipped. The system converts polygons into
+  // non-rotated rectangles.
+  //
+  // Note that the pipeline will resize the image if the image resolution is too
+  // large to process (above 50MP).
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if the image_uri is missing or longer than 4096
+  //   characters.
+  // * Returns INVALID_ARGUMENT if the product does not exist.
+  // * Returns INVALID_ARGUMENT if bounding_poly is not provided, and nothing
+  //   compatible with the parent product's product_category is detected.
+  // * Returns INVALID_ARGUMENT if bounding_poly contains more than 10 polygons.
+  rpc CreateReferenceImage(CreateReferenceImageRequest) returns (ReferenceImage) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages"
+      body: "reference_image"
+    };
+  }
+
+  // Permanently deletes a reference image.
+  //
+  // The image metadata will be deleted right away, but search queries
+  // against ProductSets containing the image may still work until all related
+  // caches are refreshed.
+  //
+  // The actual image files are not deleted from Google Cloud Storage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the reference image does not exist.
+  rpc DeleteReferenceImage(DeleteReferenceImageRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}"
+    };
+  }
+
+  // Lists reference images.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the parent product does not exist.
+  // * Returns INVALID_ARGUMENT if the page_size is greater than 100, or less
+  //   than 1.
+  rpc ListReferenceImages(ListReferenceImagesRequest) returns (ListReferenceImagesResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages"
+    };
+  }
+
+  // Gets information associated with a ReferenceImage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the specified image does not exist.
+  rpc GetReferenceImage(GetReferenceImageRequest) returns (ReferenceImage) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}"
+    };
+  }
+
+  // Adds a Product to the specified ProductSet. If the Product is already
+  // present, no change is made.
+  //
+  // One Product can be added to at most 100 ProductSets.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product or the ProductSet doesn't exist.
+  rpc AddProductToProductSet(AddProductToProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}:addProduct"
+      body: "*"
+    };
+  }
+
+  // Removes a Product from the specified ProductSet.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND If the Product is not found under the ProductSet.
+  rpc RemoveProductFromProductSet(RemoveProductFromProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}:removeProduct"
+      body: "*"
+    };
+  }
+
+  // Lists the Products in a ProductSet, in an unspecified order. If the
+  // ProductSet does not exist, the products field of the response will be
+  // empty.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
+  rpc ListProductsInProductSet(ListProductsInProductSetRequest) returns (ListProductsInProductSetResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}/products"
+    };
+  }
+
+  // Asynchronous API that imports a list of reference images to specified
+  // product sets based on a list of image information.
+  //
+  // The [google.longrunning.Operation][google.longrunning.Operation] API can be used to keep track of the
+  // progress and results of the request.
+  // `Operation.metadata` contains `BatchOperationMetadata`. (progress)
+  // `Operation.response` contains `ImportProductSetsResponse`. (results)
+  //
+  // The input source of this method is a csv file on Google Cloud Storage.
+  // For the format of the csv file please see
+  // [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p3beta1.ImportProductSetsGcsSource.csv_file_uri].
+  rpc ImportProductSets(ImportProductSetsRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/productSets:import"
+      body: "*"
+    };
+  }
+}
+
+// A Product contains ReferenceImages.
+message Product {
+  // A product label represented as a key-value pair.
+  message KeyValue {
+    // The key of the label attached to the product. Cannot be empty and cannot
+    // exceed 128 bytes.
+    string key = 1;
+
+    // The value of the label attached to the product. Cannot be empty and
+    // cannot exceed 128 bytes.
+    string value = 2;
+  }
+
+  // The resource name of the product.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  //
+  // This field is ignored when creating a product.
+  string name = 1;
+
+  // The user-provided name for this Product. Must not be empty. Must be at most
+  // 4096 characters long.
+  string display_name = 2;
+
+  // User-provided metadata to be stored with this product. Must be at most 4096
+  // characters long.
+  string description = 3;
+
+  // The category for the product identified by the reference image. This should
+  // be either "homegoods" or "apparel".
+  //
+  // This field is immutable.
+  string product_category = 4;
+
+  // Key-value pairs that can be attached to a product. At query time,
+  // constraints can be specified based on the product_labels.
+  //
+  // Note that integer values can be provided as strings, e.g. "1199". Only
+  // strings with integer values can match a range-based restriction which is
+  // to be supported soon.
+  //
+  // Multiple values can be assigned to the same key. One product may have up to
+  // 100 product_labels.
+  repeated KeyValue product_labels = 5;
+}
+
+// A ProductSet contains Products. A ProductSet can contain a maximum of 1
+// million reference images. If the limit is exceeded, periodic indexing will
+// fail.
+message ProductSet {
+  // The resource name of the ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`.
+  //
+  // This field is ignored when creating a ProductSet.
+  string name = 1;
+
+  // The user-provided name for this ProductSet. Must not be empty. Must be at
+  // most 4096 characters long.
+  string display_name = 2;
+
+  // Output only. The time at which this ProductSet was last indexed. Query
+  // results will reflect all updates before this time. If this ProductSet has
+  // never been indexed, this field is 0.
+  //
+  // This field is ignored when creating a ProductSet.
+  google.protobuf.Timestamp index_time = 3;
+
+  // Output only. If there was an error with indexing the product set, the field
+  // is populated.
+  //
+  // This field is ignored when creating a ProductSet.
+  google.rpc.Status index_error = 4;
+}
+
+// A `ReferenceImage` represents a product image and its associated metadata,
+// such as bounding boxes.
+message ReferenceImage {
+  // The resource name of the reference image.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`.
+  //
+  // This field is ignored when creating a reference image.
+  string name = 1;
+
+  // The Google Cloud Storage URI of the reference image.
+  //
+  // The URI must start with `gs://`.
+  //
+  // Required.
+  string uri = 2;
+
+  // Bounding polygons around the areas of interest in the reference image.
+  // Optional. If this field is empty, the system will try to detect regions of
+  // interest. At most 10 bounding polygons will be used.
+  //
+  // The provided shape is converted into a non-rotated rectangle. Once
+  // converted, the small edge of the rectangle must be greater than or equal
+  // to 300 pixels. The aspect ratio must be 1:4 or less (i.e. 1:3 is ok; 1:5
+  // is not).
+  repeated BoundingPoly bounding_polys = 3;
+}
+
+// Request message for the `CreateProduct` method.
+message CreateProductRequest {
+  // The project in which the Product should be created.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The product to create.
+  Product product = 2;
+
+  // A user-supplied resource id for this Product. If set, the server will
+  // attempt to use this value as the resource id. If it is already in use, an
+  // error is returned with code ALREADY_EXISTS. Must be at most 128 characters
+  // long. It cannot contain the character `/`.
+  string product_id = 3;
+}
+
+// Request message for the `ListProducts` method.
+message ListProductsRequest {
+  // The project OR ProductSet from which Products should be listed.
+  //
+  // Format:
+  // `projects/PROJECT_ID/locations/LOC_ID`
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProducts` method.
+message ListProductsResponse {
+  // List of products.
+  repeated Product products = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// Request message for the `GetProduct` method.
+message GetProductRequest {
+  // Resource name of the Product to get.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string name = 1;
+}
+
+// Request message for the `UpdateProduct` method.
+message UpdateProductRequest {
+  // The Product resource which replaces the one on the server.
+  // product.name is immutable.
+  Product product = 1;
+
+  // The [FieldMask][google.protobuf.FieldMask] that specifies which fields
+  // to update.
+  // If update_mask isn't specified, all mutable fields are to be updated.
+  // Valid mask paths include `product_labels`, `display_name` and
+  // `description`.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for the `DeleteProduct` method.
+message DeleteProductRequest {
+  // Resource name of product to delete.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string name = 1;
+}
+
+// Request message for the `CreateProductSet` method.
+message CreateProductSetRequest {
+  // The project in which the ProductSet should be created.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The ProductSet to create.
+  ProductSet product_set = 2;
+
+  // A user-supplied resource id for this ProductSet. If set, the server will
+  // attempt to use this value as the resource id. If it is already in use, an
+  // error is returned with code ALREADY_EXISTS. Must be at most 128 characters
+  // long. It cannot contain the character `/`.
+  string product_set_id = 3;
+}
+
+// Request message for the `ListProductSets` method.
+message ListProductSetsRequest {
+  // The project from which ProductSets should be listed.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProductSets` method.
+message ListProductSetsResponse {
+  // List of ProductSets.
+  repeated ProductSet product_sets = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// Request message for the `GetProductSet` method.
+message GetProductSetRequest {
+  // Resource name of the ProductSet to get.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOG_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+}
+
+// Request message for the `UpdateProductSet` method.
+message UpdateProductSetRequest {
+  // The ProductSet resource which replaces the one on the server.
+  ProductSet product_set = 1;
+
+  // The [FieldMask][google.protobuf.FieldMask] that specifies which fields to
+  // update.
+  // If update_mask isn't specified, all mutable fields are to be updated.
+  // Valid mask path is `display_name`.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for the `DeleteProductSet` method.
+message DeleteProductSetRequest {
+  // Resource name of the ProductSet to delete.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+}
+
+// Request message for the `CreateReferenceImage` method.
+message CreateReferenceImageRequest {
+  // Resource name of the product in which to create the reference image.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  string parent = 1;
+
+  // The reference image to create.
+  // If an image ID is specified, it is ignored.
+  ReferenceImage reference_image = 2;
+
+  // A user-supplied resource id for the ReferenceImage to be added. If set,
+  // the server will attempt to use this value as the resource id. If it is
+  // already in use, an error is returned with code ALREADY_EXISTS. Must be at
+  // most 128 characters long. It cannot contain the character `/`.
+  string reference_image_id = 3;
+}
+
+// Request message for the `ListReferenceImages` method.
+message ListReferenceImagesRequest {
+  // Resource name of the product containing the reference images.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // A token identifying a page of results to be returned. This is the value
+  // of `nextPageToken` returned in a previous reference image list request.
+  //
+  // Defaults to the first page if not specified.
+  string page_token = 3;
+}
+
+// Response message for the `ListReferenceImages` method.
+message ListReferenceImagesResponse {
+  // The list of reference images.
+  repeated ReferenceImage reference_images = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string next_page_token = 3;
+}
+
+// Request message for the `GetReferenceImage` method.
+message GetReferenceImageRequest {
+  // The resource name of the ReferenceImage to get.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`.
+  string name = 1;
+}
+
+// Request message for the `DeleteReferenceImage` method.
+message DeleteReferenceImageRequest {
+  // The resource name of the reference image to delete.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`
+  string name = 1;
+}
+
+// Request message for the `AddProductToProductSet` method.
+message AddProductToProductSetRequest {
+  // The resource name for the ProductSet to modify.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The resource name for the Product to be added to this ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string product = 2;
+}
+
+// Request message for the `RemoveProductFromProductSet` method.
+message RemoveProductFromProductSetRequest {
+  // The resource name for the ProductSet to modify.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The resource name for the Product to be removed from this ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string product = 2;
+}
+
+// Request message for the `ListProductsInProductSet` method.
+message ListProductsInProductSetRequest {
+  // The ProductSet resource for which to retrieve Products.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProductsInProductSet` method.
+message ListProductsInProductSetResponse {
+  // The list of Products.
+  repeated Product products = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// The Google Cloud Storage location for a csv file which preserves a list of
+// ImportProductSetRequests in each line.
+message ImportProductSetsGcsSource {
+  // The Google Cloud Storage URI of the input csv file.
+  //
+  // The URI must start with gs://
+  //
+  // The format of the input csv file should be one image per line.
+  // In each line, there are 6 columns.
+  // 1. image_uri
+  // 2, image_id
+  // 3. product_set_id
+  // 4. product_id
+  // 5, product_category
+  // 6, product_display_name
+  // 7, labels
+  // 8. bounding_poly
+  //
+  // Columns 1, 3, 4, and 5 are required, other columns are optional. A new
+  // ProductSet/Product with the same id will be created on the fly
+  // if the ProductSet/Product specified by product_set_id/product_id does not
+  // exist.
+  //
+  // The image_id field is optional but has to be unique if provided. If it is
+  // empty, we will automatically assign an unique id to the image.
+  //
+  // The product_display_name field is optional. If it is empty, a space (" ")
+  // is used as the place holder for the product display_name, which can
+  // be updated later through the realtime API.
+  //
+  // If the Product with product_id already exists, the fields
+  // product_display_name, product_category and labels are ignored.
+  //
+  // If a Product doesn't exist and needs to be created on the fly, the
+  // product_display_name field refers to [Product.display_name][google.cloud.vision.v1p3beta1.Product.display_name], the
+  // product_category field refers to [Product.product_category][google.cloud.vision.v1p3beta1.Product.product_category], and the
+  // labels field refers to [Product.labels][].
+  //
+  // Labels (optional) should be a line containing a list of comma-separated
+  // key-value pairs, with the format
+  //     "key_1=value_1,key_2=value_2,...,key_n=value_n".
+  //
+  // The bounding_poly (optional) field is used to identify one region of
+  // interest from the image in the same manner as CreateReferenceImage. If no
+  // bounding_poly is specified, the system will try to detect regions of
+  // interest automatically.
+  //
+  // Note that the pipeline will resize the image if the image resolution is too
+  // large to process (above 20MP).
+  //
+  // Also note that at most one bounding_poly is allowed per line. If the image
+  // contains multiple regions of interest, the csv should contain one line per
+  // region of interest.
+  //
+  // The bounding_poly column should contain an even number of comma-separated
+  // numbers, with the format "p1_x,p1_y,p2_x,p2_y,...,pn_x,pn_y". Nonnegative
+  // integers should be used for absolute bounding polygons, and float values
+  // in [0, 1] should be used for normalized bounding polygons.
+  string csv_file_uri = 1;
+}
+
+// The input content for the `ImportProductSets` method.
+message ImportProductSetsInputConfig {
+  // The source of the input.
+  oneof source {
+    // The Google Cloud Storage location for a csv file which preserves a list
+    // of ImportProductSetRequests in each line.
+    ImportProductSetsGcsSource gcs_source = 1;
+  }
+}
+
+// Request message for the `ImportProductSets` method.
+message ImportProductSetsRequest {
+  // The project in which the ProductSets should be imported.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The input content for the list of requests.
+  ImportProductSetsInputConfig input_config = 2;
+}
+
+// Response message for the `ImportProductSets` method.
+//
+// This message is returned by the
+// [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] method in the returned
+// [google.longrunning.Operation.response][google.longrunning.Operation.response] field.
+message ImportProductSetsResponse {
+  // The list of reference_images that are imported successfully.
+  repeated ReferenceImage reference_images = 1;
+
+  // The rpc status for each ImportProductSet request, including both successes
+  // and errors.
+  //
+  // The number of statuses here matches the number of lines in the csv file,
+  // and statuses[i] stores the success or failure status of processing the i-th
+  // line of the csv, starting from line 0.
+  repeated google.rpc.Status statuses = 2;
+}
+
+// Metadata for the batch operations such as the current state.
+//
+// This is included in the `metadata` field of the `Operation` returned by the
+// `GetOperation` call of the `google::longrunning::Operations` service.
+message BatchOperationMetadata {
+  // Enumerates the possible states that the batch request can be in.
+  enum State {
+    // Invalid.
+    STATE_UNSPECIFIED = 0;
+
+    // Request is actively being processed.
+    PROCESSING = 1;
+
+    // The request is done and at least one item has been successfully
+    // processed.
+    SUCCESSFUL = 2;
+
+    // The request is done and no item has been successfully processed.
+    FAILED = 3;
+
+    // The request is done after the longrunning.Operations.CancelOperation has
+    // been called by the user.  Any records that were processed before the
+    // cancel command are output as specified in the request.
+    CANCELLED = 4;
+  }
+
+  // The current state of the batch operation.
+  State state = 1;
+
+  // The time when the batch request was submitted to the server.
+  google.protobuf.Timestamp submit_time = 2;
+
+  // The time when the batch request is finished and
+  // [google.longrunning.Operation.done][google.longrunning.Operation.done] is set to true.
+  google.protobuf.Timestamp end_time = 3;
+}
diff --git a/vision/google/cloud/vision_v1p1beta1/proto/text_annotation.proto b/vision/google/cloud/vision_v1p1beta1/proto/text_annotation.proto
new file mode 100644
index 000000000000..928e6e88bb07
--- /dev/null
+++ b/vision/google/cloud/vision_v1p1beta1/proto/text_annotation.proto
@@ -0,0 +1,252 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p1beta1/geometry.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "TextAnnotationProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// TextAnnotation contains a structured representation of OCR extracted text.
+// The hierarchy of an OCR extracted text structure is like this:
+//     TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol
+// Each structural component, starting from Page, may further have their own
+// properties. Properties describe detected languages, breaks etc.. Please refer
+// to the
+// [TextAnnotation.TextProperty][google.cloud.vision.v1p1beta1.TextAnnotation.TextProperty]
+// message definition below for more detail.
+message TextAnnotation {
+  // Detected language for a structural component.
+  message DetectedLanguage {
+    // The BCP-47 language code, such as "en-US" or "sr-Latn". For more
+    // information, see
+    // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+    string language_code = 1;
+
+    // Confidence of detected language. Range [0, 1].
+    float confidence = 2;
+  }
+
+  // Detected start or end of a structural component.
+  message DetectedBreak {
+    // Enum to denote the type of break found. New line, space etc.
+    enum BreakType {
+      // Unknown break label type.
+      UNKNOWN = 0;
+
+      // Regular space.
+      SPACE = 1;
+
+      // Sure space (very wide).
+      SURE_SPACE = 2;
+
+      // Line-wrapping break.
+      EOL_SURE_SPACE = 3;
+
+      // End-line hyphen that is not present in text; does not co-occur with
+      // `SPACE`, `LEADER_SPACE`, or `LINE_BREAK`.
+      HYPHEN = 4;
+
+      // Line break that ends a paragraph.
+      LINE_BREAK = 5;
+    }
+
+    // Detected break type.
+    BreakType type = 1;
+
+    // True if break prepends the element.
+    bool is_prefix = 2;
+  }
+
+  // Additional information detected on the structural component.
+  message TextProperty {
+    // A list of detected languages together with confidence.
+    repeated DetectedLanguage detected_languages = 1;
+
+    // Detected start or end of a text segment.
+    DetectedBreak detected_break = 2;
+  }
+
+  // List of pages detected by OCR.
+  repeated Page pages = 1;
+
+  // UTF-8 text detected on the pages.
+  string text = 2;
+}
+
+// Detected page from OCR.
+message Page {
+  // Additional information detected on the page.
+  TextAnnotation.TextProperty property = 1;
+
+  // Page width in pixels.
+  int32 width = 2;
+
+  // Page height in pixels.
+  int32 height = 3;
+
+  // List of blocks of text, images etc on this page.
+  repeated Block blocks = 4;
+
+  // Confidence of the OCR results on the page. Range [0, 1].
+  float confidence = 5;
+}
+
+// Logical element on the page.
+message Block {
+  // Type of a block (text, image etc) as identified by OCR.
+  enum BlockType {
+    // Unknown block type.
+    UNKNOWN = 0;
+
+    // Regular text block.
+    TEXT = 1;
+
+    // Table block.
+    TABLE = 2;
+
+    // Image block.
+    PICTURE = 3;
+
+    // Horizontal/vertical line box.
+    RULER = 4;
+
+    // Barcode block.
+    BARCODE = 5;
+  }
+
+  // Additional information detected for the block.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the block.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of paragraphs in this block (if this blocks is of type text).
+  repeated Paragraph paragraphs = 3;
+
+  // Detected block type (text, image etc) for this block.
+  BlockType block_type = 4;
+
+  // Confidence of the OCR results on the block. Range [0, 1].
+  float confidence = 5;
+}
+
+// Structural unit of text representing a number of words in certain order.
+message Paragraph {
+  // Additional information detected for the paragraph.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the paragraph.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of words in this paragraph.
+  repeated Word words = 3;
+
+  // Confidence of the OCR results for the paragraph. Range [0, 1].
+  float confidence = 4;
+}
+
+// A word representation.
+message Word {
+  // Additional information detected for the word.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the word.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of symbols in the word.
+  // The order of the symbols follows the natural reading order.
+  repeated Symbol symbols = 3;
+
+  // Confidence of the OCR results for the word. Range [0, 1].
+  float confidence = 4;
+}
+
+// A single symbol representation.
+message Symbol {
+  // Additional information detected for the symbol.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the symbol.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // The actual UTF-8 representation of the symbol.
+  string text = 3;
+
+  // Confidence of the OCR results for the symbol. Range [0, 1].
+  float confidence = 4;
+}
diff --git a/vision/google/cloud/vision_v1p1beta1/proto/web_detection.proto b/vision/google/cloud/vision_v1p1beta1/proto/web_detection.proto
new file mode 100644
index 000000000000..28249cbdec22
--- /dev/null
+++ b/vision/google/cloud/vision_v1p1beta1/proto/web_detection.proto
@@ -0,0 +1,104 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "WebDetectionProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// Relevant information for the image from the Internet.
+message WebDetection {
+  // Entity deduced from similar images on the Internet.
+  message WebEntity {
+    // Opaque entity ID.
+    string entity_id = 1;
+
+    // Overall relevancy score for the entity.
+    // Not normalized and not comparable across different image queries.
+    float score = 2;
+
+    // Canonical description of the entity, in English.
+    string description = 3;
+  }
+
+  // Metadata for online images.
+  message WebImage {
+    // The result image URL.
+    string url = 1;
+
+    // (Deprecated) Overall relevancy score for the image.
+    float score = 2;
+  }
+
+  // Metadata for web pages.
+  message WebPage {
+    // The result web page URL.
+    string url = 1;
+
+    // (Deprecated) Overall relevancy score for the web page.
+    float score = 2;
+
+    // Title for the web page, may contain HTML markups.
+    string page_title = 3;
+
+    // Fully matching images on the page.
+    // Can include resized copies of the query image.
+    repeated WebImage full_matching_images = 4;
+
+    // Partial matching images on the page.
+    // Those images are similar enough to share some key-point features. For
+    // example an original image will likely have partial matching for its
+    // crops.
+    repeated WebImage partial_matching_images = 5;
+  }
+
+  // Label to provide extra metadata for the web detection.
+  message WebLabel {
+    // Label for extra metadata.
+    string label = 1;
+
+    // The BCP-47 language code for `label`, such as "en-US" or "sr-Latn".
+    // For more information, see
+    // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+    string language_code = 2;
+  }
+
+  // Deduced entities from similar images on the Internet.
+  repeated WebEntity web_entities = 1;
+
+  // Fully matching images from the Internet.
+  // Can include resized copies of the query image.
+  repeated WebImage full_matching_images = 2;
+
+  // Partial matching images from the Internet.
+  // Those images are similar enough to share some key-point features. For
+  // example an original image will likely have partial matching for its crops.
+  repeated WebImage partial_matching_images = 3;
+
+  // Web pages containing the matching images from the Internet.
+  repeated WebPage pages_with_matching_images = 4;
+
+  // The visually similar image results.
+  repeated WebImage visually_similar_images = 6;
+
+  // Best guess text labels for the request image.
+  repeated WebLabel best_guess_labels = 8;
+}
diff --git a/vision/google/cloud/vision_v1p2beta1/proto/geometry.proto b/vision/google/cloud/vision_v1p2beta1/proto/geometry.proto
new file mode 100644
index 000000000000..6d46d9c342ec
--- /dev/null
+++ b/vision/google/cloud/vision_v1p2beta1/proto/geometry.proto
@@ -0,0 +1,53 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "GeometryProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// A vertex represents a 2D point in the image.
+// NOTE: the vertex coordinates are in the same scale as the original image.
+message Vertex {
+  // X coordinate.
+  int32 x = 1;
+
+  // Y coordinate.
+  int32 y = 2;
+}
+
+// A bounding polygon for the detected image annotation.
+message BoundingPoly {
+  // The bounding polygon vertices.
+  repeated Vertex vertices = 1;
+}
+
+// A 3D position in the image, used primarily for Face detection landmarks.
+// A valid Position must have both x and y coordinates.
+// The position coordinates are in the same scale as the original image.
+message Position {
+  // X coordinate.
+  float x = 1;
+
+  // Y coordinate.
+  float y = 2;
+
+  // Z coordinate (or depth).
+  float z = 3;
+}
diff --git a/vision/google/cloud/vision_v1p2beta1/proto/image_annotator.proto b/vision/google/cloud/vision_v1p2beta1/proto/image_annotator.proto
new file mode 100644
index 000000000000..73b8db853aad
--- /dev/null
+++ b/vision/google/cloud/vision_v1p2beta1/proto/image_annotator.proto
@@ -0,0 +1,591 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p1beta1/geometry.proto";
+import "google/cloud/vision/v1p1beta1/text_annotation.proto";
+import "google/cloud/vision/v1p1beta1/web_detection.proto";
+import "google/rpc/status.proto";
+import "google/type/color.proto";
+import "google/type/latlng.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ImageAnnotatorProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// Service that performs Google Cloud Vision API detection tasks over client
+// images, such as face, landmark, logo, label, and text detection. The
+// ImageAnnotator service returns detected entities from the images.
+service ImageAnnotator {
+  // Run image detection and annotation for a batch of images.
+  rpc BatchAnnotateImages(BatchAnnotateImagesRequest)
+      returns (BatchAnnotateImagesResponse) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/images:annotate"
+      body: "*"
+    };
+  }
+}
+
+// Users describe the type of Google Cloud Vision API tasks to perform over
+// images by using *Feature*s. Each Feature indicates a type of image
+// detection task to perform. Features encode the Cloud Vision API
+// vertical to operate on and the number of top-scoring results to return.
+message Feature {
+  // Type of image feature.
+  enum Type {
+    // Unspecified feature type.
+    TYPE_UNSPECIFIED = 0;
+
+    // Run face detection.
+    FACE_DETECTION = 1;
+
+    // Run landmark detection.
+    LANDMARK_DETECTION = 2;
+
+    // Run logo detection.
+    LOGO_DETECTION = 3;
+
+    // Run label detection.
+    LABEL_DETECTION = 4;
+
+    // Run OCR.
+    TEXT_DETECTION = 5;
+
+    // Run dense text document OCR. Takes precedence when both
+    // DOCUMENT_TEXT_DETECTION and TEXT_DETECTION are present.
+    DOCUMENT_TEXT_DETECTION = 11;
+
+    // Run computer vision models to compute image safe-search properties.
+    SAFE_SEARCH_DETECTION = 6;
+
+    // Compute a set of image properties, such as the image's dominant colors.
+    IMAGE_PROPERTIES = 7;
+
+    // Run crop hints.
+    CROP_HINTS = 9;
+
+    // Run web detection.
+    WEB_DETECTION = 10;
+  }
+
+  // The feature type.
+  Type type = 1;
+
+  // Maximum number of results of this type.
+  int32 max_results = 2;
+
+  // Model to use for the feature.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 3;
+}
+
+// External image source (Google Cloud Storage image location).
+message ImageSource {
+  // NOTE: For new code `image_uri` below is preferred.
+  // Google Cloud Storage image URI, which must be in the following form:
+  // `gs://bucket_name/object_name` (for details, see
+  // [Google Cloud Storage Request
+  // URIs](https://cloud.google.com/storage/docs/reference-uris)).
+  // NOTE: Cloud Storage object versioning is not supported.
+  string gcs_image_uri = 1;
+
+  // Image URI which supports:
+  // 1) Google Cloud Storage image URI, which must be in the following form:
+  // `gs://bucket_name/object_name` (for details, see
+  // [Google Cloud Storage Request
+  // URIs](https://cloud.google.com/storage/docs/reference-uris)).
+  // NOTE: Cloud Storage object versioning is not supported.
+  // 2) Publicly accessible image HTTP/HTTPS URL.
+  // This is preferred over the legacy `gcs_image_uri` above. When both
+  // `gcs_image_uri` and `image_uri` are specified, `image_uri` takes
+  // precedence.
+  string image_uri = 2;
+}
+
+// Client image to perform Google Cloud Vision API tasks over.
+message Image {
+  // Image content, represented as a stream of bytes.
+  // Note: as with all `bytes` fields, protobuffers use a pure binary
+  // representation, whereas JSON representations use base64.
+  bytes content = 1;
+
+  // Google Cloud Storage image location. If both `content` and `source`
+  // are provided for an image, `content` takes precedence and is
+  // used to perform the image annotation request.
+  ImageSource source = 2;
+}
+
+// A face annotation object contains the results of face detection.
+message FaceAnnotation {
+  // A face-specific landmark (for example, a face feature).
+  message Landmark {
+    // Face landmark (feature) type.
+    // Left and right are defined from the vantage of the viewer of the image
+    // without considering mirror projections typical of photos. So, `LEFT_EYE`,
+    // typically, is the person's right eye.
+    enum Type {
+      // Unknown face landmark detected. Should not be filled.
+      UNKNOWN_LANDMARK = 0;
+
+      // Left eye.
+      LEFT_EYE = 1;
+
+      // Right eye.
+      RIGHT_EYE = 2;
+
+      // Left of left eyebrow.
+      LEFT_OF_LEFT_EYEBROW = 3;
+
+      // Right of left eyebrow.
+      RIGHT_OF_LEFT_EYEBROW = 4;
+
+      // Left of right eyebrow.
+      LEFT_OF_RIGHT_EYEBROW = 5;
+
+      // Right of right eyebrow.
+      RIGHT_OF_RIGHT_EYEBROW = 6;
+
+      // Midpoint between eyes.
+      MIDPOINT_BETWEEN_EYES = 7;
+
+      // Nose tip.
+      NOSE_TIP = 8;
+
+      // Upper lip.
+      UPPER_LIP = 9;
+
+      // Lower lip.
+      LOWER_LIP = 10;
+
+      // Mouth left.
+      MOUTH_LEFT = 11;
+
+      // Mouth right.
+      MOUTH_RIGHT = 12;
+
+      // Mouth center.
+      MOUTH_CENTER = 13;
+
+      // Nose, bottom right.
+      NOSE_BOTTOM_RIGHT = 14;
+
+      // Nose, bottom left.
+      NOSE_BOTTOM_LEFT = 15;
+
+      // Nose, bottom center.
+      NOSE_BOTTOM_CENTER = 16;
+
+      // Left eye, top boundary.
+      LEFT_EYE_TOP_BOUNDARY = 17;
+
+      // Left eye, right corner.
+      LEFT_EYE_RIGHT_CORNER = 18;
+
+      // Left eye, bottom boundary.
+      LEFT_EYE_BOTTOM_BOUNDARY = 19;
+
+      // Left eye, left corner.
+      LEFT_EYE_LEFT_CORNER = 20;
+
+      // Right eye, top boundary.
+      RIGHT_EYE_TOP_BOUNDARY = 21;
+
+      // Right eye, right corner.
+      RIGHT_EYE_RIGHT_CORNER = 22;
+
+      // Right eye, bottom boundary.
+      RIGHT_EYE_BOTTOM_BOUNDARY = 23;
+
+      // Right eye, left corner.
+      RIGHT_EYE_LEFT_CORNER = 24;
+
+      // Left eyebrow, upper midpoint.
+      LEFT_EYEBROW_UPPER_MIDPOINT = 25;
+
+      // Right eyebrow, upper midpoint.
+      RIGHT_EYEBROW_UPPER_MIDPOINT = 26;
+
+      // Left ear tragion.
+      LEFT_EAR_TRAGION = 27;
+
+      // Right ear tragion.
+      RIGHT_EAR_TRAGION = 28;
+
+      // Left eye pupil.
+      LEFT_EYE_PUPIL = 29;
+
+      // Right eye pupil.
+      RIGHT_EYE_PUPIL = 30;
+
+      // Forehead glabella.
+      FOREHEAD_GLABELLA = 31;
+
+      // Chin gnathion.
+      CHIN_GNATHION = 32;
+
+      // Chin left gonion.
+      CHIN_LEFT_GONION = 33;
+
+      // Chin right gonion.
+      CHIN_RIGHT_GONION = 34;
+    }
+
+    // Face landmark type.
+    Type type = 3;
+
+    // Face landmark position.
+    Position position = 4;
+  }
+
+  // The bounding polygon around the face. The coordinates of the bounding box
+  // are in the original image's scale, as returned in `ImageParams`.
+  // The bounding box is computed to "frame" the face in accordance with human
+  // expectations. It is based on the landmarker results.
+  // Note that one or more x and/or y coordinates may not be generated in the
+  // `BoundingPoly` (the polygon will be unbounded) if only a partial face
+  // appears in the image to be annotated.
+  BoundingPoly bounding_poly = 1;
+
+  // The `fd_bounding_poly` bounding polygon is tighter than the
+  // `boundingPoly`, and encloses only the skin part of the face. Typically, it
+  // is used to eliminate the face from any image analysis that detects the
+  // "amount of skin" visible in an image. It is not based on the
+  // landmarker results, only on the initial face detection, hence
+  // the <code>fd</code> (face detection) prefix.
+  BoundingPoly fd_bounding_poly = 2;
+
+  // Detected face landmarks.
+  repeated Landmark landmarks = 3;
+
+  // Roll angle, which indicates the amount of clockwise/anti-clockwise rotation
+  // of the face relative to the image vertical about the axis perpendicular to
+  // the face. Range [-180,180].
+  float roll_angle = 4;
+
+  // Yaw angle, which indicates the leftward/rightward angle that the face is
+  // pointing relative to the vertical plane perpendicular to the image. Range
+  // [-180,180].
+  float pan_angle = 5;
+
+  // Pitch angle, which indicates the upwards/downwards angle that the face is
+  // pointing relative to the image's horizontal plane. Range [-180,180].
+  float tilt_angle = 6;
+
+  // Detection confidence. Range [0, 1].
+  float detection_confidence = 7;
+
+  // Face landmarking confidence. Range [0, 1].
+  float landmarking_confidence = 8;
+
+  // Joy likelihood.
+  Likelihood joy_likelihood = 9;
+
+  // Sorrow likelihood.
+  Likelihood sorrow_likelihood = 10;
+
+  // Anger likelihood.
+  Likelihood anger_likelihood = 11;
+
+  // Surprise likelihood.
+  Likelihood surprise_likelihood = 12;
+
+  // Under-exposed likelihood.
+  Likelihood under_exposed_likelihood = 13;
+
+  // Blurred likelihood.
+  Likelihood blurred_likelihood = 14;
+
+  // Headwear likelihood.
+  Likelihood headwear_likelihood = 15;
+}
+
+// Detected entity location information.
+message LocationInfo {
+  // lat/long location coordinates.
+  google.type.LatLng lat_lng = 1;
+}
+
+// A `Property` consists of a user-supplied name/value pair.
+message Property {
+  // Name of the property.
+  string name = 1;
+
+  // Value of the property.
+  string value = 2;
+
+  // Value of numeric properties.
+  uint64 uint64_value = 3;
+}
+
+// Set of detected entity features.
+message EntityAnnotation {
+  // Opaque entity ID. Some IDs may be available in
+  // [Google Knowledge Graph Search API](https://developers.google.com/knowledge-graph/).
+  string mid = 1;
+
+  // The language code for the locale in which the entity textual
+  // `description` is expressed.
+  string locale = 2;
+
+  // Entity textual description, expressed in its `locale` language.
+  string description = 3;
+
+  // Overall score of the result. Range [0, 1].
+  float score = 4;
+
+  // The accuracy of the entity detection in an image.
+  // For example, for an image in which the "Eiffel Tower" entity is detected,
+  // this field represents the confidence that there is a tower in the query
+  // image. Range [0, 1].
+  float confidence = 5;
+
+  // The relevancy of the ICA (Image Content Annotation) label to the
+  // image. For example, the relevancy of "tower" is likely higher to an image
+  // containing the detected "Eiffel Tower" than to an image containing a
+  // detected distant towering building, even though the confidence that
+  // there is a tower in each image may be the same. Range [0, 1].
+  float topicality = 6;
+
+  // Image region to which this entity belongs. Not produced
+  // for `LABEL_DETECTION` features.
+  BoundingPoly bounding_poly = 7;
+
+  // The location information for the detected entity. Multiple
+  // `LocationInfo` elements can be present because one location may
+  // indicate the location of the scene in the image, and another location
+  // may indicate the location of the place where the image was taken.
+  // Location information is usually present for landmarks.
+  repeated LocationInfo locations = 8;
+
+  // Some entities may have optional user-supplied `Property` (name/value)
+  // fields, such a score or string that qualifies the entity.
+  repeated Property properties = 9;
+}
+
+// Set of features pertaining to the image, computed by computer vision
+// methods over safe-search verticals (for example, adult, spoof, medical,
+// violence).
+message SafeSearchAnnotation {
+  // Represents the adult content likelihood for the image. Adult content may
+  // contain elements such as nudity, pornographic images or cartoons, or
+  // sexual activities.
+  Likelihood adult = 1;
+
+  // Spoof likelihood. The likelihood that an modification
+  // was made to the image's canonical version to make it appear
+  // funny or offensive.
+  Likelihood spoof = 2;
+
+  // Likelihood that this is a medical image.
+  Likelihood medical = 3;
+
+  // Likelihood that this image contains violent content.
+  Likelihood violence = 4;
+
+  // Likelihood that the request image contains racy content. Racy content may
+  // include (but is not limited to) skimpy or sheer clothing, strategically
+  // covered nudity, lewd or provocative poses, or close-ups of sensitive
+  // body areas.
+  Likelihood racy = 9;
+}
+
+// Rectangle determined by min and max `LatLng` pairs.
+message LatLongRect {
+  // Min lat/long pair.
+  google.type.LatLng min_lat_lng = 1;
+
+  // Max lat/long pair.
+  google.type.LatLng max_lat_lng = 2;
+}
+
+// Color information consists of RGB channels, score, and the fraction of
+// the image that the color occupies in the image.
+message ColorInfo {
+  // RGB components of the color.
+  google.type.Color color = 1;
+
+  // Image-specific score for this color. Value in range [0, 1].
+  float score = 2;
+
+  // The fraction of pixels the color occupies in the image.
+  // Value in range [0, 1].
+  float pixel_fraction = 3;
+}
+
+// Set of dominant colors and their corresponding scores.
+message DominantColorsAnnotation {
+  // RGB color values with their score and pixel fraction.
+  repeated ColorInfo colors = 1;
+}
+
+// Stores image properties, such as dominant colors.
+message ImageProperties {
+  // If present, dominant colors completed successfully.
+  DominantColorsAnnotation dominant_colors = 1;
+}
+
+// Single crop hint that is used to generate a new crop when serving an image.
+message CropHint {
+  // The bounding polygon for the crop region. The coordinates of the bounding
+  // box are in the original image's scale, as returned in `ImageParams`.
+  BoundingPoly bounding_poly = 1;
+
+  // Confidence of this being a salient region.  Range [0, 1].
+  float confidence = 2;
+
+  // Fraction of importance of this salient region with respect to the original
+  // image.
+  float importance_fraction = 3;
+}
+
+// Set of crop hints that are used to generate new crops when serving images.
+message CropHintsAnnotation {
+  // Crop hint results.
+  repeated CropHint crop_hints = 1;
+}
+
+// Parameters for crop hints annotation request.
+message CropHintsParams {
+  // Aspect ratios in floats, representing the ratio of the width to the height
+  // of the image. For example, if the desired aspect ratio is 4/3, the
+  // corresponding float value should be 1.33333.  If not specified, the
+  // best possible crop is returned. The number of provided aspect ratios is
+  // limited to a maximum of 16; any aspect ratios provided after the 16th are
+  // ignored.
+  repeated float aspect_ratios = 1;
+}
+
+// Parameters for web detection request.
+message WebDetectionParams {
+  // Whether to include results derived from the geo information in the image.
+  bool include_geo_results = 2;
+}
+
+// Image context and/or feature-specific parameters.
+message ImageContext {
+  // lat/long rectangle that specifies the location of the image.
+  LatLongRect lat_long_rect = 1;
+
+  // List of languages to use for TEXT_DETECTION. In most cases, an empty value
+  // yields the best results since it enables automatic language detection. For
+  // languages based on the Latin alphabet, setting `language_hints` is not
+  // needed. In rare cases, when the language of the text in the image is known,
+  // setting a hint will help get better results (although it will be a
+  // significant hindrance if the hint is wrong). Text detection returns an
+  // error if one or more of the specified languages is not one of the
+  // [supported languages](/vision/docs/languages).
+  repeated string language_hints = 2;
+
+  // Parameters for crop hints annotation request.
+  CropHintsParams crop_hints_params = 4;
+
+  // Parameters for web detection.
+  WebDetectionParams web_detection_params = 6;
+}
+
+// Request for performing Google Cloud Vision API tasks over a user-provided
+// image, with user-requested features.
+message AnnotateImageRequest {
+  // The image to be processed.
+  Image image = 1;
+
+  // Requested features.
+  repeated Feature features = 2;
+
+  // Additional context that may accompany the image.
+  ImageContext image_context = 3;
+}
+
+// Response to an image annotation request.
+message AnnotateImageResponse {
+  // If present, face detection has completed successfully.
+  repeated FaceAnnotation face_annotations = 1;
+
+  // If present, landmark detection has completed successfully.
+  repeated EntityAnnotation landmark_annotations = 2;
+
+  // If present, logo detection has completed successfully.
+  repeated EntityAnnotation logo_annotations = 3;
+
+  // If present, label detection has completed successfully.
+  repeated EntityAnnotation label_annotations = 4;
+
+  // If present, text (OCR) detection has completed successfully.
+  repeated EntityAnnotation text_annotations = 5;
+
+  // If present, text (OCR) detection or document (OCR) text detection has
+  // completed successfully.
+  // This annotation provides the structural hierarchy for the OCR detected
+  // text.
+  TextAnnotation full_text_annotation = 12;
+
+  // If present, safe-search annotation has completed successfully.
+  SafeSearchAnnotation safe_search_annotation = 6;
+
+  // If present, image properties were extracted successfully.
+  ImageProperties image_properties_annotation = 8;
+
+  // If present, crop hints have completed successfully.
+  CropHintsAnnotation crop_hints_annotation = 11;
+
+  // If present, web detection has completed successfully.
+  WebDetection web_detection = 13;
+
+  // If set, represents the error message for the operation.
+  // Note that filled-in image annotations are guaranteed to be
+  // correct, even when `error` is set.
+  google.rpc.Status error = 9;
+}
+
+// Multiple image annotation requests are batched into a single service call.
+message BatchAnnotateImagesRequest {
+  // Individual image annotation requests for this batch.
+  repeated AnnotateImageRequest requests = 1;
+}
+
+// Response to a batch image annotation request.
+message BatchAnnotateImagesResponse {
+  // Individual responses to image annotation requests within the batch.
+  repeated AnnotateImageResponse responses = 1;
+}
+
+// A bucketized representation of likelihood, which is intended to give clients
+// highly stable results across model upgrades.
+enum Likelihood {
+  // Unknown likelihood.
+  UNKNOWN = 0;
+
+  // It is very unlikely that the image belongs to the specified vertical.
+  VERY_UNLIKELY = 1;
+
+  // It is unlikely that the image belongs to the specified vertical.
+  UNLIKELY = 2;
+
+  // It is possible that the image belongs to the specified vertical.
+  POSSIBLE = 3;
+
+  // It is likely that the image belongs to the specified vertical.
+  LIKELY = 4;
+
+  // It is very likely that the image belongs to the specified vertical.
+  VERY_LIKELY = 5;
+}
diff --git a/vision/google/cloud/vision_v1p2beta1/proto/product_search.proto b/vision/google/cloud/vision_v1p2beta1/proto/product_search.proto
new file mode 100644
index 000000000000..85e4e0784e1c
--- /dev/null
+++ b/vision/google/cloud/vision_v1p2beta1/proto/product_search.proto
@@ -0,0 +1,161 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p3beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p3beta1/geometry.proto";
+import "google/cloud/vision/v1p3beta1/product_search_service.proto";
+import "google/protobuf/timestamp.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ProductSearchProto";
+option java_package = "com.google.cloud.vision.v1p3beta1";
+
+
+// Parameters for a product search request.
+message ProductSearchParams {
+  // The resource name of the catalog to search.
+  //
+  // Format is: `productSearch/catalogs/CATALOG_NAME`.
+  string catalog_name = 1;
+
+  // The category to search in.
+  // Optional. It is inferred by the system if it is not specified.
+  // [Deprecated] Use `product_category`.
+  ProductSearchCategory category = 2;
+
+  // The product category to search in.
+  // Optional. It is inferred by the system if it is not specified.
+  // Supported values are `bag`, `shoe`, `sunglasses`, `dress`, `outerwear`,
+  // `skirt`, `top`, `shorts`, and `pants`.
+  string product_category = 5;
+
+  // The bounding polygon around the area of interest in the image.
+  // Optional. If it is not specified, system discretion will be applied.
+  // [Deprecated] Use `bounding_poly`.
+  NormalizedBoundingPoly normalized_bounding_poly = 3;
+
+  // The bounding polygon around the area of interest in the image.
+  // Optional. If it is not specified, system discretion will be applied.
+  BoundingPoly bounding_poly = 9;
+
+  // Specifies the verbosity of the  product search results.
+  // Optional. Defaults to `BASIC`.
+  ProductSearchResultsView view = 4;
+
+  // The resource name of a [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] to be searched for similar images.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`.
+  string product_set = 6;
+
+  // The list of product categories to search in. Currently, we only consider
+  // the first category, and either "homegoods" or "apparel" should be
+  // specified.
+  repeated string product_categories = 7;
+
+  // The filtering expression. This can be used to restrict search results based
+  // on Product labels. We currently support an AND of OR of key-value
+  // expressions, where each expression within an OR must have the same key.
+  //
+  // For example, "(color = red OR color = blue) AND brand = Google" is
+  // acceptable, but not "(color = red OR brand = Google)" or "color: red".
+  string filter = 8;
+}
+
+// Results for a product search request.
+message ProductSearchResults {
+  // Information about a product.
+  message ProductInfo {
+    // Product ID.
+    string product_id = 1;
+
+    // The URI of the image which matched the query image.
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    string image_uri = 2;
+
+    // A confidence level on the match, ranging from 0 (no confidence) to
+    // 1 (full confidence).
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    float score = 3;
+  }
+
+  // Information about a product.
+  message Result {
+    // The Product.
+    Product product = 1;
+
+    // A confidence level on the match, ranging from 0 (no confidence) to
+    // 1 (full confidence).
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    float score = 2;
+
+    // The resource name of the image from the product that is the closest match
+    // to the query.
+    string image = 3;
+  }
+
+  // Product category.
+  // [Deprecated] Use `product_category`.
+  ProductSearchCategory category = 1;
+
+  // Product category.
+  // Supported values are `bag` and `shoe`.
+  // [Deprecated] `product_category` is provided in each Product.
+  string product_category = 4;
+
+  // Timestamp of the index which provided these results. Changes made after
+  // this time are not reflected in the current results.
+  google.protobuf.Timestamp index_time = 2;
+
+  // List of detected products.
+  repeated ProductInfo products = 3;
+
+  // List of results, one for each product match.
+  repeated Result results = 5;
+}
+
+// Supported product search categories.
+enum ProductSearchCategory {
+  // Default value used when a category is not specified.
+  PRODUCT_SEARCH_CATEGORY_UNSPECIFIED = 0;
+
+  // Shoes category.
+  SHOES = 1;
+
+  // Bags category.
+  BAGS = 2;
+}
+
+// Specifies the fields to include in product search results.
+enum ProductSearchResultsView {
+  // Product search results contain only `product_category` and `product_id`.
+  // Default value.
+  BASIC = 0;
+
+  // Product search results contain `product_category`, `product_id`,
+  // `image_uri`, and `score`.
+  FULL = 1;
+}
diff --git a/vision/google/cloud/vision_v1p2beta1/proto/product_search_service.proto b/vision/google/cloud/vision_v1p2beta1/proto/product_search_service.proto
new file mode 100644
index 000000000000..90388e36e228
--- /dev/null
+++ b/vision/google/cloud/vision_v1p2beta1/proto/product_search_service.proto
@@ -0,0 +1,825 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p3beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p3beta1/geometry.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ProductSearchServiceProto";
+option java_package = "com.google.cloud.vision.v1p3beta1";
+
+
+// Manages Products and ProductSets of reference images for use in product
+// search. It uses the following resource model:
+//
+// - The API has a collection of [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] resources, named
+// `projects/*/locations/*/productSets/*`, which acts as a way to put different
+// products into groups to limit identification.
+//
+// In parallel,
+//
+// - The API has a collection of [Product][google.cloud.vision.v1p3beta1.Product] resources, named
+//   `projects/*/locations/*/products/*`
+//
+// - Each [Product][google.cloud.vision.v1p3beta1.Product] has a collection of [ReferenceImage][google.cloud.vision.v1p3beta1.ReferenceImage] resources, named
+//   `projects/*/locations/*/products/*/referenceImages/*`
+service ProductSearch {
+  // Creates and returns a new ProductSet resource.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if display_name is missing, or is longer than
+  //   4096 characters.
+  rpc CreateProductSet(CreateProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/productSets"
+      body: "product_set"
+    };
+  }
+
+  // Lists ProductSets in an unspecified order.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100, or less
+  //   than 1.
+  rpc ListProductSets(ListProductSetsRequest) returns (ListProductSetsResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*}/productSets"
+    };
+  }
+
+  // Gets information associated with a ProductSet.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  rpc GetProductSet(GetProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}"
+    };
+  }
+
+  // Makes changes to a ProductSet resource.
+  // Only display_name can be updated currently.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  // * Returns INVALID_ARGUMENT if display_name is present in update_mask but
+  //   missing from the request or longer than 4096 characters.
+  rpc UpdateProductSet(UpdateProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      patch: "/v1p3beta1/{product_set.name=projects/*/locations/*/productSets/*}"
+      body: "product_set"
+    };
+  }
+
+  // Permanently deletes a ProductSet. All Products and ReferenceImages in the
+  // ProductSet will be deleted.
+  //
+  // The actual image files are not deleted from Google Cloud Storage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  rpc DeleteProductSet(DeleteProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}"
+    };
+  }
+
+  // Creates and returns a new product resource.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if display_name is missing or longer than 4096
+  //   characters.
+  // * Returns INVALID_ARGUMENT if description is longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if product_category is missing or invalid.
+  rpc CreateProduct(CreateProductRequest) returns (Product) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/products"
+      body: "product"
+    };
+  }
+
+  // Lists products in an unspecified order.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
+  rpc ListProducts(ListProductsRequest) returns (ListProductsResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*}/products"
+    };
+  }
+
+  // Gets information associated with a Product.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product does not exist.
+  rpc GetProduct(GetProductRequest) returns (Product) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/products/*}"
+    };
+  }
+
+  // Makes changes to a Product resource.
+  // Only display_name, description and labels can be updated right now.
+  //
+  // If labels are updated, the change will not be reflected in queries until
+  // the next index time.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product does not exist.
+  // * Returns INVALID_ARGUMENT if display_name is present in update_mask but is
+  //   missing from the request or longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if description is present in update_mask but is
+  //   longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if product_category is present in update_mask.
+  rpc UpdateProduct(UpdateProductRequest) returns (Product) {
+    option (google.api.http) = {
+      patch: "/v1p3beta1/{product.name=projects/*/locations/*/products/*}"
+      body: "product"
+    };
+  }
+
+  // Permanently deletes a product and its reference images.
+  //
+  // Metadata of the product and all its images will be deleted right away, but
+  // search queries against ProductSets containing the product may still work
+  // until all related caches are refreshed.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the product does not exist.
+  rpc DeleteProduct(DeleteProductRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/products/*}"
+    };
+  }
+
+  // Creates and returns a new ReferenceImage resource.
+  //
+  // The `bounding_poly` field is optional. If `bounding_poly` is not specified,
+  // the system will try to detect regions of interest in the image that are
+  // compatible with the product_category on the parent product. If it is
+  // specified, detection is ALWAYS skipped. The system converts polygons into
+  // non-rotated rectangles.
+  //
+  // Note that the pipeline will resize the image if the image resolution is too
+  // large to process (above 50MP).
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if the image_uri is missing or longer than 4096
+  //   characters.
+  // * Returns INVALID_ARGUMENT if the product does not exist.
+  // * Returns INVALID_ARGUMENT if bounding_poly is not provided, and nothing
+  //   compatible with the parent product's product_category is detected.
+  // * Returns INVALID_ARGUMENT if bounding_poly contains more than 10 polygons.
+  rpc CreateReferenceImage(CreateReferenceImageRequest) returns (ReferenceImage) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages"
+      body: "reference_image"
+    };
+  }
+
+  // Permanently deletes a reference image.
+  //
+  // The image metadata will be deleted right away, but search queries
+  // against ProductSets containing the image may still work until all related
+  // caches are refreshed.
+  //
+  // The actual image files are not deleted from Google Cloud Storage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the reference image does not exist.
+  rpc DeleteReferenceImage(DeleteReferenceImageRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}"
+    };
+  }
+
+  // Lists reference images.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the parent product does not exist.
+  // * Returns INVALID_ARGUMENT if the page_size is greater than 100, or less
+  //   than 1.
+  rpc ListReferenceImages(ListReferenceImagesRequest) returns (ListReferenceImagesResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages"
+    };
+  }
+
+  // Gets information associated with a ReferenceImage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the specified image does not exist.
+  rpc GetReferenceImage(GetReferenceImageRequest) returns (ReferenceImage) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}"
+    };
+  }
+
+  // Adds a Product to the specified ProductSet. If the Product is already
+  // present, no change is made.
+  //
+  // One Product can be added to at most 100 ProductSets.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product or the ProductSet doesn't exist.
+  rpc AddProductToProductSet(AddProductToProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}:addProduct"
+      body: "*"
+    };
+  }
+
+  // Removes a Product from the specified ProductSet.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND If the Product is not found under the ProductSet.
+  rpc RemoveProductFromProductSet(RemoveProductFromProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}:removeProduct"
+      body: "*"
+    };
+  }
+
+  // Lists the Products in a ProductSet, in an unspecified order. If the
+  // ProductSet does not exist, the products field of the response will be
+  // empty.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
+  rpc ListProductsInProductSet(ListProductsInProductSetRequest) returns (ListProductsInProductSetResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}/products"
+    };
+  }
+
+  // Asynchronous API that imports a list of reference images to specified
+  // product sets based on a list of image information.
+  //
+  // The [google.longrunning.Operation][google.longrunning.Operation] API can be used to keep track of the
+  // progress and results of the request.
+  // `Operation.metadata` contains `BatchOperationMetadata`. (progress)
+  // `Operation.response` contains `ImportProductSetsResponse`. (results)
+  //
+  // The input source of this method is a csv file on Google Cloud Storage.
+  // For the format of the csv file please see
+  // [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p3beta1.ImportProductSetsGcsSource.csv_file_uri].
+  rpc ImportProductSets(ImportProductSetsRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/productSets:import"
+      body: "*"
+    };
+  }
+}
+
+// A Product contains ReferenceImages.
+message Product {
+  // A product label represented as a key-value pair.
+  message KeyValue {
+    // The key of the label attached to the product. Cannot be empty and cannot
+    // exceed 128 bytes.
+    string key = 1;
+
+    // The value of the label attached to the product. Cannot be empty and
+    // cannot exceed 128 bytes.
+    string value = 2;
+  }
+
+  // The resource name of the product.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  //
+  // This field is ignored when creating a product.
+  string name = 1;
+
+  // The user-provided name for this Product. Must not be empty. Must be at most
+  // 4096 characters long.
+  string display_name = 2;
+
+  // User-provided metadata to be stored with this product. Must be at most 4096
+  // characters long.
+  string description = 3;
+
+  // The category for the product identified by the reference image. This should
+  // be either "homegoods" or "apparel".
+  //
+  // This field is immutable.
+  string product_category = 4;
+
+  // Key-value pairs that can be attached to a product. At query time,
+  // constraints can be specified based on the product_labels.
+  //
+  // Note that integer values can be provided as strings, e.g. "1199". Only
+  // strings with integer values can match a range-based restriction which is
+  // to be supported soon.
+  //
+  // Multiple values can be assigned to the same key. One product may have up to
+  // 100 product_labels.
+  repeated KeyValue product_labels = 5;
+}
+
+// A ProductSet contains Products. A ProductSet can contain a maximum of 1
+// million reference images. If the limit is exceeded, periodic indexing will
+// fail.
+message ProductSet {
+  // The resource name of the ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`.
+  //
+  // This field is ignored when creating a ProductSet.
+  string name = 1;
+
+  // The user-provided name for this ProductSet. Must not be empty. Must be at
+  // most 4096 characters long.
+  string display_name = 2;
+
+  // Output only. The time at which this ProductSet was last indexed. Query
+  // results will reflect all updates before this time. If this ProductSet has
+  // never been indexed, this field is 0.
+  //
+  // This field is ignored when creating a ProductSet.
+  google.protobuf.Timestamp index_time = 3;
+
+  // Output only. If there was an error with indexing the product set, the field
+  // is populated.
+  //
+  // This field is ignored when creating a ProductSet.
+  google.rpc.Status index_error = 4;
+}
+
+// A `ReferenceImage` represents a product image and its associated metadata,
+// such as bounding boxes.
+message ReferenceImage {
+  // The resource name of the reference image.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`.
+  //
+  // This field is ignored when creating a reference image.
+  string name = 1;
+
+  // The Google Cloud Storage URI of the reference image.
+  //
+  // The URI must start with `gs://`.
+  //
+  // Required.
+  string uri = 2;
+
+  // Bounding polygons around the areas of interest in the reference image.
+  // Optional. If this field is empty, the system will try to detect regions of
+  // interest. At most 10 bounding polygons will be used.
+  //
+  // The provided shape is converted into a non-rotated rectangle. Once
+  // converted, the small edge of the rectangle must be greater than or equal
+  // to 300 pixels. The aspect ratio must be 1:4 or less (i.e. 1:3 is ok; 1:5
+  // is not).
+  repeated BoundingPoly bounding_polys = 3;
+}
+
+// Request message for the `CreateProduct` method.
+message CreateProductRequest {
+  // The project in which the Product should be created.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The product to create.
+  Product product = 2;
+
+  // A user-supplied resource id for this Product. If set, the server will
+  // attempt to use this value as the resource id. If it is already in use, an
+  // error is returned with code ALREADY_EXISTS. Must be at most 128 characters
+  // long. It cannot contain the character `/`.
+  string product_id = 3;
+}
+
+// Request message for the `ListProducts` method.
+message ListProductsRequest {
+  // The project OR ProductSet from which Products should be listed.
+  //
+  // Format:
+  // `projects/PROJECT_ID/locations/LOC_ID`
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProducts` method.
+message ListProductsResponse {
+  // List of products.
+  repeated Product products = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// Request message for the `GetProduct` method.
+message GetProductRequest {
+  // Resource name of the Product to get.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string name = 1;
+}
+
+// Request message for the `UpdateProduct` method.
+message UpdateProductRequest {
+  // The Product resource which replaces the one on the server.
+  // product.name is immutable.
+  Product product = 1;
+
+  // The [FieldMask][google.protobuf.FieldMask] that specifies which fields
+  // to update.
+  // If update_mask isn't specified, all mutable fields are to be updated.
+  // Valid mask paths include `product_labels`, `display_name` and
+  // `description`.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for the `DeleteProduct` method.
+message DeleteProductRequest {
+  // Resource name of product to delete.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string name = 1;
+}
+
+// Request message for the `CreateProductSet` method.
+message CreateProductSetRequest {
+  // The project in which the ProductSet should be created.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The ProductSet to create.
+  ProductSet product_set = 2;
+
+  // A user-supplied resource id for this ProductSet. If set, the server will
+  // attempt to use this value as the resource id. If it is already in use, an
+  // error is returned with code ALREADY_EXISTS. Must be at most 128 characters
+  // long. It cannot contain the character `/`.
+  string product_set_id = 3;
+}
+
+// Request message for the `ListProductSets` method.
+message ListProductSetsRequest {
+  // The project from which ProductSets should be listed.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProductSets` method.
+message ListProductSetsResponse {
+  // List of ProductSets.
+  repeated ProductSet product_sets = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// Request message for the `GetProductSet` method.
+message GetProductSetRequest {
+  // Resource name of the ProductSet to get.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOG_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+}
+
+// Request message for the `UpdateProductSet` method.
+message UpdateProductSetRequest {
+  // The ProductSet resource which replaces the one on the server.
+  ProductSet product_set = 1;
+
+  // The [FieldMask][google.protobuf.FieldMask] that specifies which fields to
+  // update.
+  // If update_mask isn't specified, all mutable fields are to be updated.
+  // Valid mask path is `display_name`.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for the `DeleteProductSet` method.
+message DeleteProductSetRequest {
+  // Resource name of the ProductSet to delete.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+}
+
+// Request message for the `CreateReferenceImage` method.
+message CreateReferenceImageRequest {
+  // Resource name of the product in which to create the reference image.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  string parent = 1;
+
+  // The reference image to create.
+  // If an image ID is specified, it is ignored.
+  ReferenceImage reference_image = 2;
+
+  // A user-supplied resource id for the ReferenceImage to be added. If set,
+  // the server will attempt to use this value as the resource id. If it is
+  // already in use, an error is returned with code ALREADY_EXISTS. Must be at
+  // most 128 characters long. It cannot contain the character `/`.
+  string reference_image_id = 3;
+}
+
+// Request message for the `ListReferenceImages` method.
+message ListReferenceImagesRequest {
+  // Resource name of the product containing the reference images.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // A token identifying a page of results to be returned. This is the value
+  // of `nextPageToken` returned in a previous reference image list request.
+  //
+  // Defaults to the first page if not specified.
+  string page_token = 3;
+}
+
+// Response message for the `ListReferenceImages` method.
+message ListReferenceImagesResponse {
+  // The list of reference images.
+  repeated ReferenceImage reference_images = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string next_page_token = 3;
+}
+
+// Request message for the `GetReferenceImage` method.
+message GetReferenceImageRequest {
+  // The resource name of the ReferenceImage to get.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`.
+  string name = 1;
+}
+
+// Request message for the `DeleteReferenceImage` method.
+message DeleteReferenceImageRequest {
+  // The resource name of the reference image to delete.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`
+  string name = 1;
+}
+
+// Request message for the `AddProductToProductSet` method.
+message AddProductToProductSetRequest {
+  // The resource name for the ProductSet to modify.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The resource name for the Product to be added to this ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string product = 2;
+}
+
+// Request message for the `RemoveProductFromProductSet` method.
+message RemoveProductFromProductSetRequest {
+  // The resource name for the ProductSet to modify.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The resource name for the Product to be removed from this ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string product = 2;
+}
+
+// Request message for the `ListProductsInProductSet` method.
+message ListProductsInProductSetRequest {
+  // The ProductSet resource for which to retrieve Products.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProductsInProductSet` method.
+message ListProductsInProductSetResponse {
+  // The list of Products.
+  repeated Product products = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// The Google Cloud Storage location for a csv file which preserves a list of
+// ImportProductSetRequests in each line.
+message ImportProductSetsGcsSource {
+  // The Google Cloud Storage URI of the input csv file.
+  //
+  // The URI must start with gs://
+  //
+  // The format of the input csv file should be one image per line.
+  // In each line, there are 6 columns.
+  // 1. image_uri
+  // 2, image_id
+  // 3. product_set_id
+  // 4. product_id
+  // 5, product_category
+  // 6, product_display_name
+  // 7, labels
+  // 8. bounding_poly
+  //
+  // Columns 1, 3, 4, and 5 are required, other columns are optional. A new
+  // ProductSet/Product with the same id will be created on the fly
+  // if the ProductSet/Product specified by product_set_id/product_id does not
+  // exist.
+  //
+  // The image_id field is optional but has to be unique if provided. If it is
+  // empty, we will automatically assign an unique id to the image.
+  //
+  // The product_display_name field is optional. If it is empty, a space (" ")
+  // is used as the place holder for the product display_name, which can
+  // be updated later through the realtime API.
+  //
+  // If the Product with product_id already exists, the fields
+  // product_display_name, product_category and labels are ignored.
+  //
+  // If a Product doesn't exist and needs to be created on the fly, the
+  // product_display_name field refers to [Product.display_name][google.cloud.vision.v1p3beta1.Product.display_name], the
+  // product_category field refers to [Product.product_category][google.cloud.vision.v1p3beta1.Product.product_category], and the
+  // labels field refers to [Product.labels][].
+  //
+  // Labels (optional) should be a line containing a list of comma-separated
+  // key-value pairs, with the format
+  //     "key_1=value_1,key_2=value_2,...,key_n=value_n".
+  //
+  // The bounding_poly (optional) field is used to identify one region of
+  // interest from the image in the same manner as CreateReferenceImage. If no
+  // bounding_poly is specified, the system will try to detect regions of
+  // interest automatically.
+  //
+  // Note that the pipeline will resize the image if the image resolution is too
+  // large to process (above 20MP).
+  //
+  // Also note that at most one bounding_poly is allowed per line. If the image
+  // contains multiple regions of interest, the csv should contain one line per
+  // region of interest.
+  //
+  // The bounding_poly column should contain an even number of comma-separated
+  // numbers, with the format "p1_x,p1_y,p2_x,p2_y,...,pn_x,pn_y". Nonnegative
+  // integers should be used for absolute bounding polygons, and float values
+  // in [0, 1] should be used for normalized bounding polygons.
+  string csv_file_uri = 1;
+}
+
+// The input content for the `ImportProductSets` method.
+message ImportProductSetsInputConfig {
+  // The source of the input.
+  oneof source {
+    // The Google Cloud Storage location for a csv file which preserves a list
+    // of ImportProductSetRequests in each line.
+    ImportProductSetsGcsSource gcs_source = 1;
+  }
+}
+
+// Request message for the `ImportProductSets` method.
+message ImportProductSetsRequest {
+  // The project in which the ProductSets should be imported.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The input content for the list of requests.
+  ImportProductSetsInputConfig input_config = 2;
+}
+
+// Response message for the `ImportProductSets` method.
+//
+// This message is returned by the
+// [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] method in the returned
+// [google.longrunning.Operation.response][google.longrunning.Operation.response] field.
+message ImportProductSetsResponse {
+  // The list of reference_images that are imported successfully.
+  repeated ReferenceImage reference_images = 1;
+
+  // The rpc status for each ImportProductSet request, including both successes
+  // and errors.
+  //
+  // The number of statuses here matches the number of lines in the csv file,
+  // and statuses[i] stores the success or failure status of processing the i-th
+  // line of the csv, starting from line 0.
+  repeated google.rpc.Status statuses = 2;
+}
+
+// Metadata for the batch operations such as the current state.
+//
+// This is included in the `metadata` field of the `Operation` returned by the
+// `GetOperation` call of the `google::longrunning::Operations` service.
+message BatchOperationMetadata {
+  // Enumerates the possible states that the batch request can be in.
+  enum State {
+    // Invalid.
+    STATE_UNSPECIFIED = 0;
+
+    // Request is actively being processed.
+    PROCESSING = 1;
+
+    // The request is done and at least one item has been successfully
+    // processed.
+    SUCCESSFUL = 2;
+
+    // The request is done and no item has been successfully processed.
+    FAILED = 3;
+
+    // The request is done after the longrunning.Operations.CancelOperation has
+    // been called by the user.  Any records that were processed before the
+    // cancel command are output as specified in the request.
+    CANCELLED = 4;
+  }
+
+  // The current state of the batch operation.
+  State state = 1;
+
+  // The time when the batch request was submitted to the server.
+  google.protobuf.Timestamp submit_time = 2;
+
+  // The time when the batch request is finished and
+  // [google.longrunning.Operation.done][google.longrunning.Operation.done] is set to true.
+  google.protobuf.Timestamp end_time = 3;
+}
diff --git a/vision/google/cloud/vision_v1p2beta1/proto/text_annotation.proto b/vision/google/cloud/vision_v1p2beta1/proto/text_annotation.proto
new file mode 100644
index 000000000000..928e6e88bb07
--- /dev/null
+++ b/vision/google/cloud/vision_v1p2beta1/proto/text_annotation.proto
@@ -0,0 +1,252 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p1beta1/geometry.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "TextAnnotationProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// TextAnnotation contains a structured representation of OCR extracted text.
+// The hierarchy of an OCR extracted text structure is like this:
+//     TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol
+// Each structural component, starting from Page, may further have their own
+// properties. Properties describe detected languages, breaks etc.. Please refer
+// to the
+// [TextAnnotation.TextProperty][google.cloud.vision.v1p1beta1.TextAnnotation.TextProperty]
+// message definition below for more detail.
+message TextAnnotation {
+  // Detected language for a structural component.
+  message DetectedLanguage {
+    // The BCP-47 language code, such as "en-US" or "sr-Latn". For more
+    // information, see
+    // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+    string language_code = 1;
+
+    // Confidence of detected language. Range [0, 1].
+    float confidence = 2;
+  }
+
+  // Detected start or end of a structural component.
+  message DetectedBreak {
+    // Enum to denote the type of break found. New line, space etc.
+    enum BreakType {
+      // Unknown break label type.
+      UNKNOWN = 0;
+
+      // Regular space.
+      SPACE = 1;
+
+      // Sure space (very wide).
+      SURE_SPACE = 2;
+
+      // Line-wrapping break.
+      EOL_SURE_SPACE = 3;
+
+      // End-line hyphen that is not present in text; does not co-occur with
+      // `SPACE`, `LEADER_SPACE`, or `LINE_BREAK`.
+      HYPHEN = 4;
+
+      // Line break that ends a paragraph.
+      LINE_BREAK = 5;
+    }
+
+    // Detected break type.
+    BreakType type = 1;
+
+    // True if break prepends the element.
+    bool is_prefix = 2;
+  }
+
+  // Additional information detected on the structural component.
+  message TextProperty {
+    // A list of detected languages together with confidence.
+    repeated DetectedLanguage detected_languages = 1;
+
+    // Detected start or end of a text segment.
+    DetectedBreak detected_break = 2;
+  }
+
+  // List of pages detected by OCR.
+  repeated Page pages = 1;
+
+  // UTF-8 text detected on the pages.
+  string text = 2;
+}
+
+// Detected page from OCR.
+message Page {
+  // Additional information detected on the page.
+  TextAnnotation.TextProperty property = 1;
+
+  // Page width in pixels.
+  int32 width = 2;
+
+  // Page height in pixels.
+  int32 height = 3;
+
+  // List of blocks of text, images etc on this page.
+  repeated Block blocks = 4;
+
+  // Confidence of the OCR results on the page. Range [0, 1].
+  float confidence = 5;
+}
+
+// Logical element on the page.
+message Block {
+  // Type of a block (text, image etc) as identified by OCR.
+  enum BlockType {
+    // Unknown block type.
+    UNKNOWN = 0;
+
+    // Regular text block.
+    TEXT = 1;
+
+    // Table block.
+    TABLE = 2;
+
+    // Image block.
+    PICTURE = 3;
+
+    // Horizontal/vertical line box.
+    RULER = 4;
+
+    // Barcode block.
+    BARCODE = 5;
+  }
+
+  // Additional information detected for the block.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the block.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of paragraphs in this block (if this blocks is of type text).
+  repeated Paragraph paragraphs = 3;
+
+  // Detected block type (text, image etc) for this block.
+  BlockType block_type = 4;
+
+  // Confidence of the OCR results on the block. Range [0, 1].
+  float confidence = 5;
+}
+
+// Structural unit of text representing a number of words in certain order.
+message Paragraph {
+  // Additional information detected for the paragraph.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the paragraph.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of words in this paragraph.
+  repeated Word words = 3;
+
+  // Confidence of the OCR results for the paragraph. Range [0, 1].
+  float confidence = 4;
+}
+
+// A word representation.
+message Word {
+  // Additional information detected for the word.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the word.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of symbols in the word.
+  // The order of the symbols follows the natural reading order.
+  repeated Symbol symbols = 3;
+
+  // Confidence of the OCR results for the word. Range [0, 1].
+  float confidence = 4;
+}
+
+// A single symbol representation.
+message Symbol {
+  // Additional information detected for the symbol.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the symbol.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // The actual UTF-8 representation of the symbol.
+  string text = 3;
+
+  // Confidence of the OCR results for the symbol. Range [0, 1].
+  float confidence = 4;
+}
diff --git a/vision/google/cloud/vision_v1p2beta1/proto/web_detection.proto b/vision/google/cloud/vision_v1p2beta1/proto/web_detection.proto
new file mode 100644
index 000000000000..28249cbdec22
--- /dev/null
+++ b/vision/google/cloud/vision_v1p2beta1/proto/web_detection.proto
@@ -0,0 +1,104 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "WebDetectionProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// Relevant information for the image from the Internet.
+message WebDetection {
+  // Entity deduced from similar images on the Internet.
+  message WebEntity {
+    // Opaque entity ID.
+    string entity_id = 1;
+
+    // Overall relevancy score for the entity.
+    // Not normalized and not comparable across different image queries.
+    float score = 2;
+
+    // Canonical description of the entity, in English.
+    string description = 3;
+  }
+
+  // Metadata for online images.
+  message WebImage {
+    // The result image URL.
+    string url = 1;
+
+    // (Deprecated) Overall relevancy score for the image.
+    float score = 2;
+  }
+
+  // Metadata for web pages.
+  message WebPage {
+    // The result web page URL.
+    string url = 1;
+
+    // (Deprecated) Overall relevancy score for the web page.
+    float score = 2;
+
+    // Title for the web page, may contain HTML markups.
+    string page_title = 3;
+
+    // Fully matching images on the page.
+    // Can include resized copies of the query image.
+    repeated WebImage full_matching_images = 4;
+
+    // Partial matching images on the page.
+    // Those images are similar enough to share some key-point features. For
+    // example an original image will likely have partial matching for its
+    // crops.
+    repeated WebImage partial_matching_images = 5;
+  }
+
+  // Label to provide extra metadata for the web detection.
+  message WebLabel {
+    // Label for extra metadata.
+    string label = 1;
+
+    // The BCP-47 language code for `label`, such as "en-US" or "sr-Latn".
+    // For more information, see
+    // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+    string language_code = 2;
+  }
+
+  // Deduced entities from similar images on the Internet.
+  repeated WebEntity web_entities = 1;
+
+  // Fully matching images from the Internet.
+  // Can include resized copies of the query image.
+  repeated WebImage full_matching_images = 2;
+
+  // Partial matching images from the Internet.
+  // Those images are similar enough to share some key-point features. For
+  // example an original image will likely have partial matching for its crops.
+  repeated WebImage partial_matching_images = 3;
+
+  // Web pages containing the matching images from the Internet.
+  repeated WebPage pages_with_matching_images = 4;
+
+  // The visually similar image results.
+  repeated WebImage visually_similar_images = 6;
+
+  // Best guess text labels for the request image.
+  repeated WebLabel best_guess_labels = 8;
+}
diff --git a/vision/google/cloud/vision_v1p3beta1/proto/geometry.proto b/vision/google/cloud/vision_v1p3beta1/proto/geometry.proto
new file mode 100644
index 000000000000..6d46d9c342ec
--- /dev/null
+++ b/vision/google/cloud/vision_v1p3beta1/proto/geometry.proto
@@ -0,0 +1,53 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "GeometryProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// A vertex represents a 2D point in the image.
+// NOTE: the vertex coordinates are in the same scale as the original image.
+message Vertex {
+  // X coordinate.
+  int32 x = 1;
+
+  // Y coordinate.
+  int32 y = 2;
+}
+
+// A bounding polygon for the detected image annotation.
+message BoundingPoly {
+  // The bounding polygon vertices.
+  repeated Vertex vertices = 1;
+}
+
+// A 3D position in the image, used primarily for Face detection landmarks.
+// A valid Position must have both x and y coordinates.
+// The position coordinates are in the same scale as the original image.
+message Position {
+  // X coordinate.
+  float x = 1;
+
+  // Y coordinate.
+  float y = 2;
+
+  // Z coordinate (or depth).
+  float z = 3;
+}
diff --git a/vision/google/cloud/vision_v1p3beta1/proto/image_annotator.proto b/vision/google/cloud/vision_v1p3beta1/proto/image_annotator.proto
new file mode 100644
index 000000000000..73b8db853aad
--- /dev/null
+++ b/vision/google/cloud/vision_v1p3beta1/proto/image_annotator.proto
@@ -0,0 +1,591 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p1beta1/geometry.proto";
+import "google/cloud/vision/v1p1beta1/text_annotation.proto";
+import "google/cloud/vision/v1p1beta1/web_detection.proto";
+import "google/rpc/status.proto";
+import "google/type/color.proto";
+import "google/type/latlng.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ImageAnnotatorProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// Service that performs Google Cloud Vision API detection tasks over client
+// images, such as face, landmark, logo, label, and text detection. The
+// ImageAnnotator service returns detected entities from the images.
+service ImageAnnotator {
+  // Run image detection and annotation for a batch of images.
+  rpc BatchAnnotateImages(BatchAnnotateImagesRequest)
+      returns (BatchAnnotateImagesResponse) {
+    option (google.api.http) = {
+      post: "/v1p1beta1/images:annotate"
+      body: "*"
+    };
+  }
+}
+
+// Users describe the type of Google Cloud Vision API tasks to perform over
+// images by using *Feature*s. Each Feature indicates a type of image
+// detection task to perform. Features encode the Cloud Vision API
+// vertical to operate on and the number of top-scoring results to return.
+message Feature {
+  // Type of image feature.
+  enum Type {
+    // Unspecified feature type.
+    TYPE_UNSPECIFIED = 0;
+
+    // Run face detection.
+    FACE_DETECTION = 1;
+
+    // Run landmark detection.
+    LANDMARK_DETECTION = 2;
+
+    // Run logo detection.
+    LOGO_DETECTION = 3;
+
+    // Run label detection.
+    LABEL_DETECTION = 4;
+
+    // Run OCR.
+    TEXT_DETECTION = 5;
+
+    // Run dense text document OCR. Takes precedence when both
+    // DOCUMENT_TEXT_DETECTION and TEXT_DETECTION are present.
+    DOCUMENT_TEXT_DETECTION = 11;
+
+    // Run computer vision models to compute image safe-search properties.
+    SAFE_SEARCH_DETECTION = 6;
+
+    // Compute a set of image properties, such as the image's dominant colors.
+    IMAGE_PROPERTIES = 7;
+
+    // Run crop hints.
+    CROP_HINTS = 9;
+
+    // Run web detection.
+    WEB_DETECTION = 10;
+  }
+
+  // The feature type.
+  Type type = 1;
+
+  // Maximum number of results of this type.
+  int32 max_results = 2;
+
+  // Model to use for the feature.
+  // Supported values: "builtin/stable" (the default if unset) and
+  // "builtin/latest".
+  string model = 3;
+}
+
+// External image source (Google Cloud Storage image location).
+message ImageSource {
+  // NOTE: For new code `image_uri` below is preferred.
+  // Google Cloud Storage image URI, which must be in the following form:
+  // `gs://bucket_name/object_name` (for details, see
+  // [Google Cloud Storage Request
+  // URIs](https://cloud.google.com/storage/docs/reference-uris)).
+  // NOTE: Cloud Storage object versioning is not supported.
+  string gcs_image_uri = 1;
+
+  // Image URI which supports:
+  // 1) Google Cloud Storage image URI, which must be in the following form:
+  // `gs://bucket_name/object_name` (for details, see
+  // [Google Cloud Storage Request
+  // URIs](https://cloud.google.com/storage/docs/reference-uris)).
+  // NOTE: Cloud Storage object versioning is not supported.
+  // 2) Publicly accessible image HTTP/HTTPS URL.
+  // This is preferred over the legacy `gcs_image_uri` above. When both
+  // `gcs_image_uri` and `image_uri` are specified, `image_uri` takes
+  // precedence.
+  string image_uri = 2;
+}
+
+// Client image to perform Google Cloud Vision API tasks over.
+message Image {
+  // Image content, represented as a stream of bytes.
+  // Note: as with all `bytes` fields, protobuffers use a pure binary
+  // representation, whereas JSON representations use base64.
+  bytes content = 1;
+
+  // Google Cloud Storage image location. If both `content` and `source`
+  // are provided for an image, `content` takes precedence and is
+  // used to perform the image annotation request.
+  ImageSource source = 2;
+}
+
+// A face annotation object contains the results of face detection.
+message FaceAnnotation {
+  // A face-specific landmark (for example, a face feature).
+  message Landmark {
+    // Face landmark (feature) type.
+    // Left and right are defined from the vantage of the viewer of the image
+    // without considering mirror projections typical of photos. So, `LEFT_EYE`,
+    // typically, is the person's right eye.
+    enum Type {
+      // Unknown face landmark detected. Should not be filled.
+      UNKNOWN_LANDMARK = 0;
+
+      // Left eye.
+      LEFT_EYE = 1;
+
+      // Right eye.
+      RIGHT_EYE = 2;
+
+      // Left of left eyebrow.
+      LEFT_OF_LEFT_EYEBROW = 3;
+
+      // Right of left eyebrow.
+      RIGHT_OF_LEFT_EYEBROW = 4;
+
+      // Left of right eyebrow.
+      LEFT_OF_RIGHT_EYEBROW = 5;
+
+      // Right of right eyebrow.
+      RIGHT_OF_RIGHT_EYEBROW = 6;
+
+      // Midpoint between eyes.
+      MIDPOINT_BETWEEN_EYES = 7;
+
+      // Nose tip.
+      NOSE_TIP = 8;
+
+      // Upper lip.
+      UPPER_LIP = 9;
+
+      // Lower lip.
+      LOWER_LIP = 10;
+
+      // Mouth left.
+      MOUTH_LEFT = 11;
+
+      // Mouth right.
+      MOUTH_RIGHT = 12;
+
+      // Mouth center.
+      MOUTH_CENTER = 13;
+
+      // Nose, bottom right.
+      NOSE_BOTTOM_RIGHT = 14;
+
+      // Nose, bottom left.
+      NOSE_BOTTOM_LEFT = 15;
+
+      // Nose, bottom center.
+      NOSE_BOTTOM_CENTER = 16;
+
+      // Left eye, top boundary.
+      LEFT_EYE_TOP_BOUNDARY = 17;
+
+      // Left eye, right corner.
+      LEFT_EYE_RIGHT_CORNER = 18;
+
+      // Left eye, bottom boundary.
+      LEFT_EYE_BOTTOM_BOUNDARY = 19;
+
+      // Left eye, left corner.
+      LEFT_EYE_LEFT_CORNER = 20;
+
+      // Right eye, top boundary.
+      RIGHT_EYE_TOP_BOUNDARY = 21;
+
+      // Right eye, right corner.
+      RIGHT_EYE_RIGHT_CORNER = 22;
+
+      // Right eye, bottom boundary.
+      RIGHT_EYE_BOTTOM_BOUNDARY = 23;
+
+      // Right eye, left corner.
+      RIGHT_EYE_LEFT_CORNER = 24;
+
+      // Left eyebrow, upper midpoint.
+      LEFT_EYEBROW_UPPER_MIDPOINT = 25;
+
+      // Right eyebrow, upper midpoint.
+      RIGHT_EYEBROW_UPPER_MIDPOINT = 26;
+
+      // Left ear tragion.
+      LEFT_EAR_TRAGION = 27;
+
+      // Right ear tragion.
+      RIGHT_EAR_TRAGION = 28;
+
+      // Left eye pupil.
+      LEFT_EYE_PUPIL = 29;
+
+      // Right eye pupil.
+      RIGHT_EYE_PUPIL = 30;
+
+      // Forehead glabella.
+      FOREHEAD_GLABELLA = 31;
+
+      // Chin gnathion.
+      CHIN_GNATHION = 32;
+
+      // Chin left gonion.
+      CHIN_LEFT_GONION = 33;
+
+      // Chin right gonion.
+      CHIN_RIGHT_GONION = 34;
+    }
+
+    // Face landmark type.
+    Type type = 3;
+
+    // Face landmark position.
+    Position position = 4;
+  }
+
+  // The bounding polygon around the face. The coordinates of the bounding box
+  // are in the original image's scale, as returned in `ImageParams`.
+  // The bounding box is computed to "frame" the face in accordance with human
+  // expectations. It is based on the landmarker results.
+  // Note that one or more x and/or y coordinates may not be generated in the
+  // `BoundingPoly` (the polygon will be unbounded) if only a partial face
+  // appears in the image to be annotated.
+  BoundingPoly bounding_poly = 1;
+
+  // The `fd_bounding_poly` bounding polygon is tighter than the
+  // `boundingPoly`, and encloses only the skin part of the face. Typically, it
+  // is used to eliminate the face from any image analysis that detects the
+  // "amount of skin" visible in an image. It is not based on the
+  // landmarker results, only on the initial face detection, hence
+  // the <code>fd</code> (face detection) prefix.
+  BoundingPoly fd_bounding_poly = 2;
+
+  // Detected face landmarks.
+  repeated Landmark landmarks = 3;
+
+  // Roll angle, which indicates the amount of clockwise/anti-clockwise rotation
+  // of the face relative to the image vertical about the axis perpendicular to
+  // the face. Range [-180,180].
+  float roll_angle = 4;
+
+  // Yaw angle, which indicates the leftward/rightward angle that the face is
+  // pointing relative to the vertical plane perpendicular to the image. Range
+  // [-180,180].
+  float pan_angle = 5;
+
+  // Pitch angle, which indicates the upwards/downwards angle that the face is
+  // pointing relative to the image's horizontal plane. Range [-180,180].
+  float tilt_angle = 6;
+
+  // Detection confidence. Range [0, 1].
+  float detection_confidence = 7;
+
+  // Face landmarking confidence. Range [0, 1].
+  float landmarking_confidence = 8;
+
+  // Joy likelihood.
+  Likelihood joy_likelihood = 9;
+
+  // Sorrow likelihood.
+  Likelihood sorrow_likelihood = 10;
+
+  // Anger likelihood.
+  Likelihood anger_likelihood = 11;
+
+  // Surprise likelihood.
+  Likelihood surprise_likelihood = 12;
+
+  // Under-exposed likelihood.
+  Likelihood under_exposed_likelihood = 13;
+
+  // Blurred likelihood.
+  Likelihood blurred_likelihood = 14;
+
+  // Headwear likelihood.
+  Likelihood headwear_likelihood = 15;
+}
+
+// Detected entity location information.
+message LocationInfo {
+  // lat/long location coordinates.
+  google.type.LatLng lat_lng = 1;
+}
+
+// A `Property` consists of a user-supplied name/value pair.
+message Property {
+  // Name of the property.
+  string name = 1;
+
+  // Value of the property.
+  string value = 2;
+
+  // Value of numeric properties.
+  uint64 uint64_value = 3;
+}
+
+// Set of detected entity features.
+message EntityAnnotation {
+  // Opaque entity ID. Some IDs may be available in
+  // [Google Knowledge Graph Search API](https://developers.google.com/knowledge-graph/).
+  string mid = 1;
+
+  // The language code for the locale in which the entity textual
+  // `description` is expressed.
+  string locale = 2;
+
+  // Entity textual description, expressed in its `locale` language.
+  string description = 3;
+
+  // Overall score of the result. Range [0, 1].
+  float score = 4;
+
+  // The accuracy of the entity detection in an image.
+  // For example, for an image in which the "Eiffel Tower" entity is detected,
+  // this field represents the confidence that there is a tower in the query
+  // image. Range [0, 1].
+  float confidence = 5;
+
+  // The relevancy of the ICA (Image Content Annotation) label to the
+  // image. For example, the relevancy of "tower" is likely higher to an image
+  // containing the detected "Eiffel Tower" than to an image containing a
+  // detected distant towering building, even though the confidence that
+  // there is a tower in each image may be the same. Range [0, 1].
+  float topicality = 6;
+
+  // Image region to which this entity belongs. Not produced
+  // for `LABEL_DETECTION` features.
+  BoundingPoly bounding_poly = 7;
+
+  // The location information for the detected entity. Multiple
+  // `LocationInfo` elements can be present because one location may
+  // indicate the location of the scene in the image, and another location
+  // may indicate the location of the place where the image was taken.
+  // Location information is usually present for landmarks.
+  repeated LocationInfo locations = 8;
+
+  // Some entities may have optional user-supplied `Property` (name/value)
+  // fields, such a score or string that qualifies the entity.
+  repeated Property properties = 9;
+}
+
+// Set of features pertaining to the image, computed by computer vision
+// methods over safe-search verticals (for example, adult, spoof, medical,
+// violence).
+message SafeSearchAnnotation {
+  // Represents the adult content likelihood for the image. Adult content may
+  // contain elements such as nudity, pornographic images or cartoons, or
+  // sexual activities.
+  Likelihood adult = 1;
+
+  // Spoof likelihood. The likelihood that an modification
+  // was made to the image's canonical version to make it appear
+  // funny or offensive.
+  Likelihood spoof = 2;
+
+  // Likelihood that this is a medical image.
+  Likelihood medical = 3;
+
+  // Likelihood that this image contains violent content.
+  Likelihood violence = 4;
+
+  // Likelihood that the request image contains racy content. Racy content may
+  // include (but is not limited to) skimpy or sheer clothing, strategically
+  // covered nudity, lewd or provocative poses, or close-ups of sensitive
+  // body areas.
+  Likelihood racy = 9;
+}
+
+// Rectangle determined by min and max `LatLng` pairs.
+message LatLongRect {
+  // Min lat/long pair.
+  google.type.LatLng min_lat_lng = 1;
+
+  // Max lat/long pair.
+  google.type.LatLng max_lat_lng = 2;
+}
+
+// Color information consists of RGB channels, score, and the fraction of
+// the image that the color occupies in the image.
+message ColorInfo {
+  // RGB components of the color.
+  google.type.Color color = 1;
+
+  // Image-specific score for this color. Value in range [0, 1].
+  float score = 2;
+
+  // The fraction of pixels the color occupies in the image.
+  // Value in range [0, 1].
+  float pixel_fraction = 3;
+}
+
+// Set of dominant colors and their corresponding scores.
+message DominantColorsAnnotation {
+  // RGB color values with their score and pixel fraction.
+  repeated ColorInfo colors = 1;
+}
+
+// Stores image properties, such as dominant colors.
+message ImageProperties {
+  // If present, dominant colors completed successfully.
+  DominantColorsAnnotation dominant_colors = 1;
+}
+
+// Single crop hint that is used to generate a new crop when serving an image.
+message CropHint {
+  // The bounding polygon for the crop region. The coordinates of the bounding
+  // box are in the original image's scale, as returned in `ImageParams`.
+  BoundingPoly bounding_poly = 1;
+
+  // Confidence of this being a salient region.  Range [0, 1].
+  float confidence = 2;
+
+  // Fraction of importance of this salient region with respect to the original
+  // image.
+  float importance_fraction = 3;
+}
+
+// Set of crop hints that are used to generate new crops when serving images.
+message CropHintsAnnotation {
+  // Crop hint results.
+  repeated CropHint crop_hints = 1;
+}
+
+// Parameters for crop hints annotation request.
+message CropHintsParams {
+  // Aspect ratios in floats, representing the ratio of the width to the height
+  // of the image. For example, if the desired aspect ratio is 4/3, the
+  // corresponding float value should be 1.33333.  If not specified, the
+  // best possible crop is returned. The number of provided aspect ratios is
+  // limited to a maximum of 16; any aspect ratios provided after the 16th are
+  // ignored.
+  repeated float aspect_ratios = 1;
+}
+
+// Parameters for web detection request.
+message WebDetectionParams {
+  // Whether to include results derived from the geo information in the image.
+  bool include_geo_results = 2;
+}
+
+// Image context and/or feature-specific parameters.
+message ImageContext {
+  // lat/long rectangle that specifies the location of the image.
+  LatLongRect lat_long_rect = 1;
+
+  // List of languages to use for TEXT_DETECTION. In most cases, an empty value
+  // yields the best results since it enables automatic language detection. For
+  // languages based on the Latin alphabet, setting `language_hints` is not
+  // needed. In rare cases, when the language of the text in the image is known,
+  // setting a hint will help get better results (although it will be a
+  // significant hindrance if the hint is wrong). Text detection returns an
+  // error if one or more of the specified languages is not one of the
+  // [supported languages](/vision/docs/languages).
+  repeated string language_hints = 2;
+
+  // Parameters for crop hints annotation request.
+  CropHintsParams crop_hints_params = 4;
+
+  // Parameters for web detection.
+  WebDetectionParams web_detection_params = 6;
+}
+
+// Request for performing Google Cloud Vision API tasks over a user-provided
+// image, with user-requested features.
+message AnnotateImageRequest {
+  // The image to be processed.
+  Image image = 1;
+
+  // Requested features.
+  repeated Feature features = 2;
+
+  // Additional context that may accompany the image.
+  ImageContext image_context = 3;
+}
+
+// Response to an image annotation request.
+message AnnotateImageResponse {
+  // If present, face detection has completed successfully.
+  repeated FaceAnnotation face_annotations = 1;
+
+  // If present, landmark detection has completed successfully.
+  repeated EntityAnnotation landmark_annotations = 2;
+
+  // If present, logo detection has completed successfully.
+  repeated EntityAnnotation logo_annotations = 3;
+
+  // If present, label detection has completed successfully.
+  repeated EntityAnnotation label_annotations = 4;
+
+  // If present, text (OCR) detection has completed successfully.
+  repeated EntityAnnotation text_annotations = 5;
+
+  // If present, text (OCR) detection or document (OCR) text detection has
+  // completed successfully.
+  // This annotation provides the structural hierarchy for the OCR detected
+  // text.
+  TextAnnotation full_text_annotation = 12;
+
+  // If present, safe-search annotation has completed successfully.
+  SafeSearchAnnotation safe_search_annotation = 6;
+
+  // If present, image properties were extracted successfully.
+  ImageProperties image_properties_annotation = 8;
+
+  // If present, crop hints have completed successfully.
+  CropHintsAnnotation crop_hints_annotation = 11;
+
+  // If present, web detection has completed successfully.
+  WebDetection web_detection = 13;
+
+  // If set, represents the error message for the operation.
+  // Note that filled-in image annotations are guaranteed to be
+  // correct, even when `error` is set.
+  google.rpc.Status error = 9;
+}
+
+// Multiple image annotation requests are batched into a single service call.
+message BatchAnnotateImagesRequest {
+  // Individual image annotation requests for this batch.
+  repeated AnnotateImageRequest requests = 1;
+}
+
+// Response to a batch image annotation request.
+message BatchAnnotateImagesResponse {
+  // Individual responses to image annotation requests within the batch.
+  repeated AnnotateImageResponse responses = 1;
+}
+
+// A bucketized representation of likelihood, which is intended to give clients
+// highly stable results across model upgrades.
+enum Likelihood {
+  // Unknown likelihood.
+  UNKNOWN = 0;
+
+  // It is very unlikely that the image belongs to the specified vertical.
+  VERY_UNLIKELY = 1;
+
+  // It is unlikely that the image belongs to the specified vertical.
+  UNLIKELY = 2;
+
+  // It is possible that the image belongs to the specified vertical.
+  POSSIBLE = 3;
+
+  // It is likely that the image belongs to the specified vertical.
+  LIKELY = 4;
+
+  // It is very likely that the image belongs to the specified vertical.
+  VERY_LIKELY = 5;
+}
diff --git a/vision/google/cloud/vision_v1p3beta1/proto/product_search.proto b/vision/google/cloud/vision_v1p3beta1/proto/product_search.proto
new file mode 100644
index 000000000000..85e4e0784e1c
--- /dev/null
+++ b/vision/google/cloud/vision_v1p3beta1/proto/product_search.proto
@@ -0,0 +1,161 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p3beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p3beta1/geometry.proto";
+import "google/cloud/vision/v1p3beta1/product_search_service.proto";
+import "google/protobuf/timestamp.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ProductSearchProto";
+option java_package = "com.google.cloud.vision.v1p3beta1";
+
+
+// Parameters for a product search request.
+message ProductSearchParams {
+  // The resource name of the catalog to search.
+  //
+  // Format is: `productSearch/catalogs/CATALOG_NAME`.
+  string catalog_name = 1;
+
+  // The category to search in.
+  // Optional. It is inferred by the system if it is not specified.
+  // [Deprecated] Use `product_category`.
+  ProductSearchCategory category = 2;
+
+  // The product category to search in.
+  // Optional. It is inferred by the system if it is not specified.
+  // Supported values are `bag`, `shoe`, `sunglasses`, `dress`, `outerwear`,
+  // `skirt`, `top`, `shorts`, and `pants`.
+  string product_category = 5;
+
+  // The bounding polygon around the area of interest in the image.
+  // Optional. If it is not specified, system discretion will be applied.
+  // [Deprecated] Use `bounding_poly`.
+  NormalizedBoundingPoly normalized_bounding_poly = 3;
+
+  // The bounding polygon around the area of interest in the image.
+  // Optional. If it is not specified, system discretion will be applied.
+  BoundingPoly bounding_poly = 9;
+
+  // Specifies the verbosity of the  product search results.
+  // Optional. Defaults to `BASIC`.
+  ProductSearchResultsView view = 4;
+
+  // The resource name of a [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] to be searched for similar images.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`.
+  string product_set = 6;
+
+  // The list of product categories to search in. Currently, we only consider
+  // the first category, and either "homegoods" or "apparel" should be
+  // specified.
+  repeated string product_categories = 7;
+
+  // The filtering expression. This can be used to restrict search results based
+  // on Product labels. We currently support an AND of OR of key-value
+  // expressions, where each expression within an OR must have the same key.
+  //
+  // For example, "(color = red OR color = blue) AND brand = Google" is
+  // acceptable, but not "(color = red OR brand = Google)" or "color: red".
+  string filter = 8;
+}
+
+// Results for a product search request.
+message ProductSearchResults {
+  // Information about a product.
+  message ProductInfo {
+    // Product ID.
+    string product_id = 1;
+
+    // The URI of the image which matched the query image.
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    string image_uri = 2;
+
+    // A confidence level on the match, ranging from 0 (no confidence) to
+    // 1 (full confidence).
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    float score = 3;
+  }
+
+  // Information about a product.
+  message Result {
+    // The Product.
+    Product product = 1;
+
+    // A confidence level on the match, ranging from 0 (no confidence) to
+    // 1 (full confidence).
+    //
+    // This field is returned only if `view` is set to `FULL` in
+    // the request.
+    float score = 2;
+
+    // The resource name of the image from the product that is the closest match
+    // to the query.
+    string image = 3;
+  }
+
+  // Product category.
+  // [Deprecated] Use `product_category`.
+  ProductSearchCategory category = 1;
+
+  // Product category.
+  // Supported values are `bag` and `shoe`.
+  // [Deprecated] `product_category` is provided in each Product.
+  string product_category = 4;
+
+  // Timestamp of the index which provided these results. Changes made after
+  // this time are not reflected in the current results.
+  google.protobuf.Timestamp index_time = 2;
+
+  // List of detected products.
+  repeated ProductInfo products = 3;
+
+  // List of results, one for each product match.
+  repeated Result results = 5;
+}
+
+// Supported product search categories.
+enum ProductSearchCategory {
+  // Default value used when a category is not specified.
+  PRODUCT_SEARCH_CATEGORY_UNSPECIFIED = 0;
+
+  // Shoes category.
+  SHOES = 1;
+
+  // Bags category.
+  BAGS = 2;
+}
+
+// Specifies the fields to include in product search results.
+enum ProductSearchResultsView {
+  // Product search results contain only `product_category` and `product_id`.
+  // Default value.
+  BASIC = 0;
+
+  // Product search results contain `product_category`, `product_id`,
+  // `image_uri`, and `score`.
+  FULL = 1;
+}
diff --git a/vision/google/cloud/vision_v1p3beta1/proto/product_search_service.proto b/vision/google/cloud/vision_v1p3beta1/proto/product_search_service.proto
new file mode 100644
index 000000000000..90388e36e228
--- /dev/null
+++ b/vision/google/cloud/vision_v1p3beta1/proto/product_search_service.proto
@@ -0,0 +1,825 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p3beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p3beta1/geometry.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+import "google/rpc/status.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p3beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "ProductSearchServiceProto";
+option java_package = "com.google.cloud.vision.v1p3beta1";
+
+
+// Manages Products and ProductSets of reference images for use in product
+// search. It uses the following resource model:
+//
+// - The API has a collection of [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] resources, named
+// `projects/*/locations/*/productSets/*`, which acts as a way to put different
+// products into groups to limit identification.
+//
+// In parallel,
+//
+// - The API has a collection of [Product][google.cloud.vision.v1p3beta1.Product] resources, named
+//   `projects/*/locations/*/products/*`
+//
+// - Each [Product][google.cloud.vision.v1p3beta1.Product] has a collection of [ReferenceImage][google.cloud.vision.v1p3beta1.ReferenceImage] resources, named
+//   `projects/*/locations/*/products/*/referenceImages/*`
+service ProductSearch {
+  // Creates and returns a new ProductSet resource.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if display_name is missing, or is longer than
+  //   4096 characters.
+  rpc CreateProductSet(CreateProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/productSets"
+      body: "product_set"
+    };
+  }
+
+  // Lists ProductSets in an unspecified order.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100, or less
+  //   than 1.
+  rpc ListProductSets(ListProductSetsRequest) returns (ListProductSetsResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*}/productSets"
+    };
+  }
+
+  // Gets information associated with a ProductSet.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  rpc GetProductSet(GetProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}"
+    };
+  }
+
+  // Makes changes to a ProductSet resource.
+  // Only display_name can be updated currently.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  // * Returns INVALID_ARGUMENT if display_name is present in update_mask but
+  //   missing from the request or longer than 4096 characters.
+  rpc UpdateProductSet(UpdateProductSetRequest) returns (ProductSet) {
+    option (google.api.http) = {
+      patch: "/v1p3beta1/{product_set.name=projects/*/locations/*/productSets/*}"
+      body: "product_set"
+    };
+  }
+
+  // Permanently deletes a ProductSet. All Products and ReferenceImages in the
+  // ProductSet will be deleted.
+  //
+  // The actual image files are not deleted from Google Cloud Storage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the ProductSet does not exist.
+  rpc DeleteProductSet(DeleteProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}"
+    };
+  }
+
+  // Creates and returns a new product resource.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if display_name is missing or longer than 4096
+  //   characters.
+  // * Returns INVALID_ARGUMENT if description is longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if product_category is missing or invalid.
+  rpc CreateProduct(CreateProductRequest) returns (Product) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/products"
+      body: "product"
+    };
+  }
+
+  // Lists products in an unspecified order.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
+  rpc ListProducts(ListProductsRequest) returns (ListProductsResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*}/products"
+    };
+  }
+
+  // Gets information associated with a Product.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product does not exist.
+  rpc GetProduct(GetProductRequest) returns (Product) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/products/*}"
+    };
+  }
+
+  // Makes changes to a Product resource.
+  // Only display_name, description and labels can be updated right now.
+  //
+  // If labels are updated, the change will not be reflected in queries until
+  // the next index time.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product does not exist.
+  // * Returns INVALID_ARGUMENT if display_name is present in update_mask but is
+  //   missing from the request or longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if description is present in update_mask but is
+  //   longer than 4096 characters.
+  // * Returns INVALID_ARGUMENT if product_category is present in update_mask.
+  rpc UpdateProduct(UpdateProductRequest) returns (Product) {
+    option (google.api.http) = {
+      patch: "/v1p3beta1/{product.name=projects/*/locations/*/products/*}"
+      body: "product"
+    };
+  }
+
+  // Permanently deletes a product and its reference images.
+  //
+  // Metadata of the product and all its images will be deleted right away, but
+  // search queries against ProductSets containing the product may still work
+  // until all related caches are refreshed.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the product does not exist.
+  rpc DeleteProduct(DeleteProductRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/products/*}"
+    };
+  }
+
+  // Creates and returns a new ReferenceImage resource.
+  //
+  // The `bounding_poly` field is optional. If `bounding_poly` is not specified,
+  // the system will try to detect regions of interest in the image that are
+  // compatible with the product_category on the parent product. If it is
+  // specified, detection is ALWAYS skipped. The system converts polygons into
+  // non-rotated rectangles.
+  //
+  // Note that the pipeline will resize the image if the image resolution is too
+  // large to process (above 50MP).
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if the image_uri is missing or longer than 4096
+  //   characters.
+  // * Returns INVALID_ARGUMENT if the product does not exist.
+  // * Returns INVALID_ARGUMENT if bounding_poly is not provided, and nothing
+  //   compatible with the parent product's product_category is detected.
+  // * Returns INVALID_ARGUMENT if bounding_poly contains more than 10 polygons.
+  rpc CreateReferenceImage(CreateReferenceImageRequest) returns (ReferenceImage) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages"
+      body: "reference_image"
+    };
+  }
+
+  // Permanently deletes a reference image.
+  //
+  // The image metadata will be deleted right away, but search queries
+  // against ProductSets containing the image may still work until all related
+  // caches are refreshed.
+  //
+  // The actual image files are not deleted from Google Cloud Storage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the reference image does not exist.
+  rpc DeleteReferenceImage(DeleteReferenceImageRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}"
+    };
+  }
+
+  // Lists reference images.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the parent product does not exist.
+  // * Returns INVALID_ARGUMENT if the page_size is greater than 100, or less
+  //   than 1.
+  rpc ListReferenceImages(ListReferenceImagesRequest) returns (ListReferenceImagesResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages"
+    };
+  }
+
+  // Gets information associated with a ReferenceImage.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the specified image does not exist.
+  rpc GetReferenceImage(GetReferenceImageRequest) returns (ReferenceImage) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}"
+    };
+  }
+
+  // Adds a Product to the specified ProductSet. If the Product is already
+  // present, no change is made.
+  //
+  // One Product can be added to at most 100 ProductSets.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND if the Product or the ProductSet doesn't exist.
+  rpc AddProductToProductSet(AddProductToProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}:addProduct"
+      body: "*"
+    };
+  }
+
+  // Removes a Product from the specified ProductSet.
+  //
+  // Possible errors:
+  //
+  // * Returns NOT_FOUND If the Product is not found under the ProductSet.
+  rpc RemoveProductFromProductSet(RemoveProductFromProductSetRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}:removeProduct"
+      body: "*"
+    };
+  }
+
+  // Lists the Products in a ProductSet, in an unspecified order. If the
+  // ProductSet does not exist, the products field of the response will be
+  // empty.
+  //
+  // Possible errors:
+  //
+  // * Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
+  rpc ListProductsInProductSet(ListProductsInProductSetRequest) returns (ListProductsInProductSetResponse) {
+    option (google.api.http) = {
+      get: "/v1p3beta1/{name=projects/*/locations/*/productSets/*}/products"
+    };
+  }
+
+  // Asynchronous API that imports a list of reference images to specified
+  // product sets based on a list of image information.
+  //
+  // The [google.longrunning.Operation][google.longrunning.Operation] API can be used to keep track of the
+  // progress and results of the request.
+  // `Operation.metadata` contains `BatchOperationMetadata`. (progress)
+  // `Operation.response` contains `ImportProductSetsResponse`. (results)
+  //
+  // The input source of this method is a csv file on Google Cloud Storage.
+  // For the format of the csv file please see
+  // [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p3beta1.ImportProductSetsGcsSource.csv_file_uri].
+  rpc ImportProductSets(ImportProductSetsRequest) returns (google.longrunning.Operation) {
+    option (google.api.http) = {
+      post: "/v1p3beta1/{parent=projects/*/locations/*}/productSets:import"
+      body: "*"
+    };
+  }
+}
+
+// A Product contains ReferenceImages.
+message Product {
+  // A product label represented as a key-value pair.
+  message KeyValue {
+    // The key of the label attached to the product. Cannot be empty and cannot
+    // exceed 128 bytes.
+    string key = 1;
+
+    // The value of the label attached to the product. Cannot be empty and
+    // cannot exceed 128 bytes.
+    string value = 2;
+  }
+
+  // The resource name of the product.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  //
+  // This field is ignored when creating a product.
+  string name = 1;
+
+  // The user-provided name for this Product. Must not be empty. Must be at most
+  // 4096 characters long.
+  string display_name = 2;
+
+  // User-provided metadata to be stored with this product. Must be at most 4096
+  // characters long.
+  string description = 3;
+
+  // The category for the product identified by the reference image. This should
+  // be either "homegoods" or "apparel".
+  //
+  // This field is immutable.
+  string product_category = 4;
+
+  // Key-value pairs that can be attached to a product. At query time,
+  // constraints can be specified based on the product_labels.
+  //
+  // Note that integer values can be provided as strings, e.g. "1199". Only
+  // strings with integer values can match a range-based restriction which is
+  // to be supported soon.
+  //
+  // Multiple values can be assigned to the same key. One product may have up to
+  // 100 product_labels.
+  repeated KeyValue product_labels = 5;
+}
+
+// A ProductSet contains Products. A ProductSet can contain a maximum of 1
+// million reference images. If the limit is exceeded, periodic indexing will
+// fail.
+message ProductSet {
+  // The resource name of the ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`.
+  //
+  // This field is ignored when creating a ProductSet.
+  string name = 1;
+
+  // The user-provided name for this ProductSet. Must not be empty. Must be at
+  // most 4096 characters long.
+  string display_name = 2;
+
+  // Output only. The time at which this ProductSet was last indexed. Query
+  // results will reflect all updates before this time. If this ProductSet has
+  // never been indexed, this field is 0.
+  //
+  // This field is ignored when creating a ProductSet.
+  google.protobuf.Timestamp index_time = 3;
+
+  // Output only. If there was an error with indexing the product set, the field
+  // is populated.
+  //
+  // This field is ignored when creating a ProductSet.
+  google.rpc.Status index_error = 4;
+}
+
+// A `ReferenceImage` represents a product image and its associated metadata,
+// such as bounding boxes.
+message ReferenceImage {
+  // The resource name of the reference image.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`.
+  //
+  // This field is ignored when creating a reference image.
+  string name = 1;
+
+  // The Google Cloud Storage URI of the reference image.
+  //
+  // The URI must start with `gs://`.
+  //
+  // Required.
+  string uri = 2;
+
+  // Bounding polygons around the areas of interest in the reference image.
+  // Optional. If this field is empty, the system will try to detect regions of
+  // interest. At most 10 bounding polygons will be used.
+  //
+  // The provided shape is converted into a non-rotated rectangle. Once
+  // converted, the small edge of the rectangle must be greater than or equal
+  // to 300 pixels. The aspect ratio must be 1:4 or less (i.e. 1:3 is ok; 1:5
+  // is not).
+  repeated BoundingPoly bounding_polys = 3;
+}
+
+// Request message for the `CreateProduct` method.
+message CreateProductRequest {
+  // The project in which the Product should be created.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The product to create.
+  Product product = 2;
+
+  // A user-supplied resource id for this Product. If set, the server will
+  // attempt to use this value as the resource id. If it is already in use, an
+  // error is returned with code ALREADY_EXISTS. Must be at most 128 characters
+  // long. It cannot contain the character `/`.
+  string product_id = 3;
+}
+
+// Request message for the `ListProducts` method.
+message ListProductsRequest {
+  // The project OR ProductSet from which Products should be listed.
+  //
+  // Format:
+  // `projects/PROJECT_ID/locations/LOC_ID`
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProducts` method.
+message ListProductsResponse {
+  // List of products.
+  repeated Product products = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// Request message for the `GetProduct` method.
+message GetProductRequest {
+  // Resource name of the Product to get.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string name = 1;
+}
+
+// Request message for the `UpdateProduct` method.
+message UpdateProductRequest {
+  // The Product resource which replaces the one on the server.
+  // product.name is immutable.
+  Product product = 1;
+
+  // The [FieldMask][google.protobuf.FieldMask] that specifies which fields
+  // to update.
+  // If update_mask isn't specified, all mutable fields are to be updated.
+  // Valid mask paths include `product_labels`, `display_name` and
+  // `description`.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for the `DeleteProduct` method.
+message DeleteProductRequest {
+  // Resource name of product to delete.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string name = 1;
+}
+
+// Request message for the `CreateProductSet` method.
+message CreateProductSetRequest {
+  // The project in which the ProductSet should be created.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The ProductSet to create.
+  ProductSet product_set = 2;
+
+  // A user-supplied resource id for this ProductSet. If set, the server will
+  // attempt to use this value as the resource id. If it is already in use, an
+  // error is returned with code ALREADY_EXISTS. Must be at most 128 characters
+  // long. It cannot contain the character `/`.
+  string product_set_id = 3;
+}
+
+// Request message for the `ListProductSets` method.
+message ListProductSetsRequest {
+  // The project from which ProductSets should be listed.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProductSets` method.
+message ListProductSetsResponse {
+  // List of ProductSets.
+  repeated ProductSet product_sets = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// Request message for the `GetProductSet` method.
+message GetProductSetRequest {
+  // Resource name of the ProductSet to get.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOG_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+}
+
+// Request message for the `UpdateProductSet` method.
+message UpdateProductSetRequest {
+  // The ProductSet resource which replaces the one on the server.
+  ProductSet product_set = 1;
+
+  // The [FieldMask][google.protobuf.FieldMask] that specifies which fields to
+  // update.
+  // If update_mask isn't specified, all mutable fields are to be updated.
+  // Valid mask path is `display_name`.
+  google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request message for the `DeleteProductSet` method.
+message DeleteProductSetRequest {
+  // Resource name of the ProductSet to delete.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+}
+
+// Request message for the `CreateReferenceImage` method.
+message CreateReferenceImageRequest {
+  // Resource name of the product in which to create the reference image.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  string parent = 1;
+
+  // The reference image to create.
+  // If an image ID is specified, it is ignored.
+  ReferenceImage reference_image = 2;
+
+  // A user-supplied resource id for the ReferenceImage to be added. If set,
+  // the server will attempt to use this value as the resource id. If it is
+  // already in use, an error is returned with code ALREADY_EXISTS. Must be at
+  // most 128 characters long. It cannot contain the character `/`.
+  string reference_image_id = 3;
+}
+
+// Request message for the `ListReferenceImages` method.
+message ListReferenceImagesRequest {
+  // Resource name of the product containing the reference images.
+  //
+  // Format is
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`.
+  string parent = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // A token identifying a page of results to be returned. This is the value
+  // of `nextPageToken` returned in a previous reference image list request.
+  //
+  // Defaults to the first page if not specified.
+  string page_token = 3;
+}
+
+// Response message for the `ListReferenceImages` method.
+message ListReferenceImagesResponse {
+  // The list of reference images.
+  repeated ReferenceImage reference_images = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string next_page_token = 3;
+}
+
+// Request message for the `GetReferenceImage` method.
+message GetReferenceImageRequest {
+  // The resource name of the ReferenceImage to get.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`.
+  string name = 1;
+}
+
+// Request message for the `DeleteReferenceImage` method.
+message DeleteReferenceImageRequest {
+  // The resource name of the reference image to delete.
+  //
+  // Format is:
+  //
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`
+  string name = 1;
+}
+
+// Request message for the `AddProductToProductSet` method.
+message AddProductToProductSetRequest {
+  // The resource name for the ProductSet to modify.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The resource name for the Product to be added to this ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string product = 2;
+}
+
+// Request message for the `RemoveProductFromProductSet` method.
+message RemoveProductFromProductSetRequest {
+  // The resource name for the ProductSet to modify.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The resource name for the Product to be removed from this ProductSet.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`
+  string product = 2;
+}
+
+// Request message for the `ListProductsInProductSet` method.
+message ListProductsInProductSetRequest {
+  // The ProductSet resource for which to retrieve Products.
+  //
+  // Format is:
+  // `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`
+  string name = 1;
+
+  // The maximum number of items to return. Default 10, maximum 100.
+  int32 page_size = 2;
+
+  // The next_page_token returned from a previous List request, if any.
+  string page_token = 3;
+}
+
+// Response message for the `ListProductsInProductSet` method.
+message ListProductsInProductSetResponse {
+  // The list of Products.
+  repeated Product products = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no more
+  // results in the list.
+  string next_page_token = 2;
+}
+
+// The Google Cloud Storage location for a csv file which preserves a list of
+// ImportProductSetRequests in each line.
+message ImportProductSetsGcsSource {
+  // The Google Cloud Storage URI of the input csv file.
+  //
+  // The URI must start with gs://
+  //
+  // The format of the input csv file should be one image per line.
+  // In each line, there are 6 columns.
+  // 1. image_uri
+  // 2, image_id
+  // 3. product_set_id
+  // 4. product_id
+  // 5, product_category
+  // 6, product_display_name
+  // 7, labels
+  // 8. bounding_poly
+  //
+  // Columns 1, 3, 4, and 5 are required, other columns are optional. A new
+  // ProductSet/Product with the same id will be created on the fly
+  // if the ProductSet/Product specified by product_set_id/product_id does not
+  // exist.
+  //
+  // The image_id field is optional but has to be unique if provided. If it is
+  // empty, we will automatically assign an unique id to the image.
+  //
+  // The product_display_name field is optional. If it is empty, a space (" ")
+  // is used as the place holder for the product display_name, which can
+  // be updated later through the realtime API.
+  //
+  // If the Product with product_id already exists, the fields
+  // product_display_name, product_category and labels are ignored.
+  //
+  // If a Product doesn't exist and needs to be created on the fly, the
+  // product_display_name field refers to [Product.display_name][google.cloud.vision.v1p3beta1.Product.display_name], the
+  // product_category field refers to [Product.product_category][google.cloud.vision.v1p3beta1.Product.product_category], and the
+  // labels field refers to [Product.labels][].
+  //
+  // Labels (optional) should be a line containing a list of comma-separated
+  // key-value pairs, with the format
+  //     "key_1=value_1,key_2=value_2,...,key_n=value_n".
+  //
+  // The bounding_poly (optional) field is used to identify one region of
+  // interest from the image in the same manner as CreateReferenceImage. If no
+  // bounding_poly is specified, the system will try to detect regions of
+  // interest automatically.
+  //
+  // Note that the pipeline will resize the image if the image resolution is too
+  // large to process (above 20MP).
+  //
+  // Also note that at most one bounding_poly is allowed per line. If the image
+  // contains multiple regions of interest, the csv should contain one line per
+  // region of interest.
+  //
+  // The bounding_poly column should contain an even number of comma-separated
+  // numbers, with the format "p1_x,p1_y,p2_x,p2_y,...,pn_x,pn_y". Nonnegative
+  // integers should be used for absolute bounding polygons, and float values
+  // in [0, 1] should be used for normalized bounding polygons.
+  string csv_file_uri = 1;
+}
+
+// The input content for the `ImportProductSets` method.
+message ImportProductSetsInputConfig {
+  // The source of the input.
+  oneof source {
+    // The Google Cloud Storage location for a csv file which preserves a list
+    // of ImportProductSetRequests in each line.
+    ImportProductSetsGcsSource gcs_source = 1;
+  }
+}
+
+// Request message for the `ImportProductSets` method.
+message ImportProductSetsRequest {
+  // The project in which the ProductSets should be imported.
+  //
+  // Format is `projects/PROJECT_ID/locations/LOC_ID`.
+  string parent = 1;
+
+  // The input content for the list of requests.
+  ImportProductSetsInputConfig input_config = 2;
+}
+
+// Response message for the `ImportProductSets` method.
+//
+// This message is returned by the
+// [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] method in the returned
+// [google.longrunning.Operation.response][google.longrunning.Operation.response] field.
+message ImportProductSetsResponse {
+  // The list of reference_images that are imported successfully.
+  repeated ReferenceImage reference_images = 1;
+
+  // The rpc status for each ImportProductSet request, including both successes
+  // and errors.
+  //
+  // The number of statuses here matches the number of lines in the csv file,
+  // and statuses[i] stores the success or failure status of processing the i-th
+  // line of the csv, starting from line 0.
+  repeated google.rpc.Status statuses = 2;
+}
+
+// Metadata for the batch operations such as the current state.
+//
+// This is included in the `metadata` field of the `Operation` returned by the
+// `GetOperation` call of the `google::longrunning::Operations` service.
+message BatchOperationMetadata {
+  // Enumerates the possible states that the batch request can be in.
+  enum State {
+    // Invalid.
+    STATE_UNSPECIFIED = 0;
+
+    // Request is actively being processed.
+    PROCESSING = 1;
+
+    // The request is done and at least one item has been successfully
+    // processed.
+    SUCCESSFUL = 2;
+
+    // The request is done and no item has been successfully processed.
+    FAILED = 3;
+
+    // The request is done after the longrunning.Operations.CancelOperation has
+    // been called by the user.  Any records that were processed before the
+    // cancel command are output as specified in the request.
+    CANCELLED = 4;
+  }
+
+  // The current state of the batch operation.
+  State state = 1;
+
+  // The time when the batch request was submitted to the server.
+  google.protobuf.Timestamp submit_time = 2;
+
+  // The time when the batch request is finished and
+  // [google.longrunning.Operation.done][google.longrunning.Operation.done] is set to true.
+  google.protobuf.Timestamp end_time = 3;
+}
diff --git a/vision/google/cloud/vision_v1p3beta1/proto/text_annotation.proto b/vision/google/cloud/vision_v1p3beta1/proto/text_annotation.proto
new file mode 100644
index 000000000000..928e6e88bb07
--- /dev/null
+++ b/vision/google/cloud/vision_v1p3beta1/proto/text_annotation.proto
@@ -0,0 +1,252 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+import "google/cloud/vision/v1p1beta1/geometry.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "TextAnnotationProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// TextAnnotation contains a structured representation of OCR extracted text.
+// The hierarchy of an OCR extracted text structure is like this:
+//     TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol
+// Each structural component, starting from Page, may further have their own
+// properties. Properties describe detected languages, breaks etc.. Please refer
+// to the
+// [TextAnnotation.TextProperty][google.cloud.vision.v1p1beta1.TextAnnotation.TextProperty]
+// message definition below for more detail.
+message TextAnnotation {
+  // Detected language for a structural component.
+  message DetectedLanguage {
+    // The BCP-47 language code, such as "en-US" or "sr-Latn". For more
+    // information, see
+    // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+    string language_code = 1;
+
+    // Confidence of detected language. Range [0, 1].
+    float confidence = 2;
+  }
+
+  // Detected start or end of a structural component.
+  message DetectedBreak {
+    // Enum to denote the type of break found. New line, space etc.
+    enum BreakType {
+      // Unknown break label type.
+      UNKNOWN = 0;
+
+      // Regular space.
+      SPACE = 1;
+
+      // Sure space (very wide).
+      SURE_SPACE = 2;
+
+      // Line-wrapping break.
+      EOL_SURE_SPACE = 3;
+
+      // End-line hyphen that is not present in text; does not co-occur with
+      // `SPACE`, `LEADER_SPACE`, or `LINE_BREAK`.
+      HYPHEN = 4;
+
+      // Line break that ends a paragraph.
+      LINE_BREAK = 5;
+    }
+
+    // Detected break type.
+    BreakType type = 1;
+
+    // True if break prepends the element.
+    bool is_prefix = 2;
+  }
+
+  // Additional information detected on the structural component.
+  message TextProperty {
+    // A list of detected languages together with confidence.
+    repeated DetectedLanguage detected_languages = 1;
+
+    // Detected start or end of a text segment.
+    DetectedBreak detected_break = 2;
+  }
+
+  // List of pages detected by OCR.
+  repeated Page pages = 1;
+
+  // UTF-8 text detected on the pages.
+  string text = 2;
+}
+
+// Detected page from OCR.
+message Page {
+  // Additional information detected on the page.
+  TextAnnotation.TextProperty property = 1;
+
+  // Page width in pixels.
+  int32 width = 2;
+
+  // Page height in pixels.
+  int32 height = 3;
+
+  // List of blocks of text, images etc on this page.
+  repeated Block blocks = 4;
+
+  // Confidence of the OCR results on the page. Range [0, 1].
+  float confidence = 5;
+}
+
+// Logical element on the page.
+message Block {
+  // Type of a block (text, image etc) as identified by OCR.
+  enum BlockType {
+    // Unknown block type.
+    UNKNOWN = 0;
+
+    // Regular text block.
+    TEXT = 1;
+
+    // Table block.
+    TABLE = 2;
+
+    // Image block.
+    PICTURE = 3;
+
+    // Horizontal/vertical line box.
+    RULER = 4;
+
+    // Barcode block.
+    BARCODE = 5;
+  }
+
+  // Additional information detected for the block.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the block.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of paragraphs in this block (if this blocks is of type text).
+  repeated Paragraph paragraphs = 3;
+
+  // Detected block type (text, image etc) for this block.
+  BlockType block_type = 4;
+
+  // Confidence of the OCR results on the block. Range [0, 1].
+  float confidence = 5;
+}
+
+// Structural unit of text representing a number of words in certain order.
+message Paragraph {
+  // Additional information detected for the paragraph.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the paragraph.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of words in this paragraph.
+  repeated Word words = 3;
+
+  // Confidence of the OCR results for the paragraph. Range [0, 1].
+  float confidence = 4;
+}
+
+// A word representation.
+message Word {
+  // Additional information detected for the word.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the word.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // List of symbols in the word.
+  // The order of the symbols follows the natural reading order.
+  repeated Symbol symbols = 3;
+
+  // Confidence of the OCR results for the word. Range [0, 1].
+  float confidence = 4;
+}
+
+// A single symbol representation.
+message Symbol {
+  // Additional information detected for the symbol.
+  TextAnnotation.TextProperty property = 1;
+
+  // The bounding box for the symbol.
+  // The vertices are in the order of top-left, top-right, bottom-right,
+  // bottom-left. When a rotation of the bounding box is detected the rotation
+  // is represented as around the top-left corner as defined when the text is
+  // read in the 'natural' orientation.
+  // For example:
+  //   * when the text is horizontal it might look like:
+  //      0----1
+  //      |    |
+  //      3----2
+  //   * when it's rotated 180 degrees around the top-left corner it becomes:
+  //      2----3
+  //      |    |
+  //      1----0
+  //   and the vertice order will still be (0, 1, 2, 3).
+  BoundingPoly bounding_box = 2;
+
+  // The actual UTF-8 representation of the symbol.
+  string text = 3;
+
+  // Confidence of the OCR results for the symbol. Range [0, 1].
+  float confidence = 4;
+}
diff --git a/vision/google/cloud/vision_v1p3beta1/proto/web_detection.proto b/vision/google/cloud/vision_v1p3beta1/proto/web_detection.proto
new file mode 100644
index 000000000000..28249cbdec22
--- /dev/null
+++ b/vision/google/cloud/vision_v1p3beta1/proto/web_detection.proto
@@ -0,0 +1,104 @@
+// Copyright 2017 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.vision.v1p1beta1;
+
+import "google/api/annotations.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1;vision";
+option java_multiple_files = true;
+option java_outer_classname = "WebDetectionProto";
+option java_package = "com.google.cloud.vision.v1p1beta1";
+
+// Relevant information for the image from the Internet.
+message WebDetection {
+  // Entity deduced from similar images on the Internet.
+  message WebEntity {
+    // Opaque entity ID.
+    string entity_id = 1;
+
+    // Overall relevancy score for the entity.
+    // Not normalized and not comparable across different image queries.
+    float score = 2;
+
+    // Canonical description of the entity, in English.
+    string description = 3;
+  }
+
+  // Metadata for online images.
+  message WebImage {
+    // The result image URL.
+    string url = 1;
+
+    // (Deprecated) Overall relevancy score for the image.
+    float score = 2;
+  }
+
+  // Metadata for web pages.
+  message WebPage {
+    // The result web page URL.
+    string url = 1;
+
+    // (Deprecated) Overall relevancy score for the web page.
+    float score = 2;
+
+    // Title for the web page, may contain HTML markups.
+    string page_title = 3;
+
+    // Fully matching images on the page.
+    // Can include resized copies of the query image.
+    repeated WebImage full_matching_images = 4;
+
+    // Partial matching images on the page.
+    // Those images are similar enough to share some key-point features. For
+    // example an original image will likely have partial matching for its
+    // crops.
+    repeated WebImage partial_matching_images = 5;
+  }
+
+  // Label to provide extra metadata for the web detection.
+  message WebLabel {
+    // Label for extra metadata.
+    string label = 1;
+
+    // The BCP-47 language code for `label`, such as "en-US" or "sr-Latn".
+    // For more information, see
+    // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+    string language_code = 2;
+  }
+
+  // Deduced entities from similar images on the Internet.
+  repeated WebEntity web_entities = 1;
+
+  // Fully matching images from the Internet.
+  // Can include resized copies of the query image.
+  repeated WebImage full_matching_images = 2;
+
+  // Partial matching images from the Internet.
+  // Those images are similar enough to share some key-point features. For
+  // example an original image will likely have partial matching for its crops.
+  repeated WebImage partial_matching_images = 3;
+
+  // Web pages containing the matching images from the Internet.
+  repeated WebPage pages_with_matching_images = 4;
+
+  // The visually similar image results.
+  repeated WebImage visually_similar_images = 6;
+
+  // Best guess text labels for the request image.
+  repeated WebLabel best_guess_labels = 8;
+}
diff --git a/vision/synth.metadata b/vision/synth.metadata
index 1f8b685af5f9..e4d343df2328 100644
--- a/vision/synth.metadata
+++ b/vision/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:33:44.664854Z",
+  "updateTime": "2019-01-24T17:50:07.082250Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/vision/synth.py b/vision/synth.py
index 6c9bbd3b413d..e6d632ffadec 100644
--- a/vision/synth.py
+++ b/vision/synth.py
@@ -26,7 +26,7 @@
 # Generate vision GAPIC layer
 # ----------------------------------------------------------------------------
 for version in versions:
-    library = gapic.py_library("vision", version)
+    library = gapic.py_library("vision", version, include_protos=True)
 
     s.move(library / f"google/cloud/vision_{version}/gapic")
     s.move(library / f"google/cloud/vision_{version}/__init__.py")
diff --git a/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/crawled_url.proto b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/crawled_url.proto
new file mode 100644
index 000000000000..8951e50bfc67
--- /dev/null
+++ b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/crawled_url.proto
@@ -0,0 +1,43 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.websecurityscanner.v1alpha;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha;websecurityscanner";
+option java_multiple_files = true;
+option java_outer_classname = "CrawledUrlProto";
+option java_package = "com.google.cloud.websecurityscanner.v1alpha";
+
+
+// A CrawledUrl resource represents a URL that was crawled during a ScanRun. Web
+// Security Scanner Service crawls the web applications, following all links
+// within the scope of sites, to find the URLs to test against.
+message CrawledUrl {
+  // Output only.
+  // The http method of the request that was used to visit the URL, in
+  // uppercase.
+  string http_method = 1;
+
+  // Output only.
+  // The URL that was crawled.
+  string url = 2;
+
+  // Output only.
+  // The body of the request that was used to visit the URL.
+  string body = 3;
+}
diff --git a/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/finding.proto b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/finding.proto
new file mode 100644
index 000000000000..bdb15152603c
--- /dev/null
+++ b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/finding.proto
@@ -0,0 +1,141 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.websecurityscanner.v1alpha;
+
+import "google/api/annotations.proto";
+import "google/cloud/websecurityscanner/v1alpha/finding_addon.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha;websecurityscanner";
+option java_multiple_files = true;
+option java_outer_classname = "FindingProto";
+option java_package = "com.google.cloud.websecurityscanner.v1alpha";
+
+
+// A Finding resource represents a vulnerability instance identified during a
+// ScanRun.
+message Finding {
+  // Types of Findings.
+  enum FindingType {
+    // The invalid finding type.
+    FINDING_TYPE_UNSPECIFIED = 0;
+
+    // A page that was served over HTTPS also resources over HTTP. A
+    // man-in-the-middle attacker could tamper with the HTTP resource and gain
+    // full access to the website that loads the resource or to monitor the
+    // actions taken by the user.
+    MIXED_CONTENT = 1;
+
+    // The version of an included library is known to contain a security issue.
+    // The scanner checks the version of library in use against a known list of
+    // vulnerable libraries. False positives are possible if the version
+    // detection fails or if the library has been manually patched.
+    OUTDATED_LIBRARY = 2;
+
+    // This type of vulnerability occurs when the value of a request parameter
+    // is reflected at the beginning of the response, for example, in requests
+    // using JSONP. Under certain circumstances, an attacker may be able to
+    // supply an alphanumeric-only Flash file in the vulnerable parameter
+    // causing the browser to execute the Flash file as if it originated on the
+    // vulnerable server.
+    ROSETTA_FLASH = 5;
+
+    // A cross-site scripting (XSS) bug is found via JavaScript callback. For
+    // detailed explanations on XSS, see
+    // https://www.google.com/about/appsecurity/learning/xss/.
+    XSS_CALLBACK = 3;
+
+    // A potential cross-site scripting (XSS) bug due to JavaScript breakage.
+    // In some circumstances, the application under test might modify the test
+    // string before it is parsed by the browser. When the browser attempts to
+    // runs this modified test string, it will likely break and throw a
+    // JavaScript execution error, thus an injection issue is occurring.
+    // However, it may not be exploitable. Manual verification is needed to see
+    // if the test string modifications can be evaded and confirm that the issue
+    // is in fact an XSS vulnerability. For detailed explanations on XSS, see
+    // https://www.google.com/about/appsecurity/learning/xss/.
+    XSS_ERROR = 4;
+
+    // An application appears to be transmitting a password field in clear text.
+    // An attacker can eavesdrop network traffic and sniff the password field.
+    CLEAR_TEXT_PASSWORD = 6;
+  }
+
+  // Output only.
+  // The resource name of the Finding. The name follows the format of
+  // 'projects/{projectId}/scanConfigs/{scanConfigId}/scanruns/{scanRunId}/findings/{findingId}'.
+  // The finding IDs are generated by the system.
+  string name = 1;
+
+  // Output only.
+  // The type of the Finding.
+  FindingType finding_type = 2;
+
+  // Output only.
+  // The http method of the request that triggered the vulnerability, in
+  // uppercase.
+  string http_method = 3;
+
+  // Output only.
+  // The URL produced by the server-side fuzzer and used in the request that
+  // triggered the vulnerability.
+  string fuzzed_url = 4;
+
+  // Output only.
+  // The body of the request that triggered the vulnerability.
+  string body = 5;
+
+  // Output only.
+  // The description of the vulnerability.
+  string description = 6;
+
+  // Output only.
+  // The URL containing human-readable payload that user can leverage to
+  // reproduce the vulnerability.
+  string reproduction_url = 7;
+
+  // Output only.
+  // If the vulnerability was originated from nested IFrame, the immediate
+  // parent IFrame is reported.
+  string frame_url = 8;
+
+  // Output only.
+  // The URL where the browser lands when the vulnerability is detected.
+  string final_url = 9;
+
+  // Output only.
+  // The tracking ID uniquely identifies a vulnerability instance across
+  // multiple ScanRuns.
+  string tracking_id = 10;
+
+  // Output only.
+  // An addon containing information about outdated libraries.
+  OutdatedLibrary outdated_library = 11;
+
+  // Output only.
+  // An addon containing detailed information regarding any resource causing the
+  // vulnerability such as JavaScript sources, image, audio files, etc.
+  ViolatingResource violating_resource = 12;
+
+  // Output only.
+  // An addon containing information about request parameters which were found
+  // to be vulnerable.
+  VulnerableParameters vulnerable_parameters = 13;
+
+  // Output only.
+  // An addon containing information reported for an XSS, if any.
+  Xss xss = 14;
+}
diff --git a/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/finding_addon.proto b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/finding_addon.proto
new file mode 100644
index 000000000000..d0777f64d683
--- /dev/null
+++ b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/finding_addon.proto
@@ -0,0 +1,62 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.websecurityscanner.v1alpha;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha;websecurityscanner";
+option java_multiple_files = true;
+option java_outer_classname = "FindingAddonProto";
+option java_package = "com.google.cloud.websecurityscanner.v1alpha";
+
+
+// Information reported for an outdated library.
+message OutdatedLibrary {
+  // The name of the outdated library.
+  string library_name = 1;
+
+  // The version number.
+  string version = 2;
+
+  // URLs to learn more information about the vulnerabilities in the library.
+  repeated string learn_more_urls = 3;
+}
+
+// Information regarding any resource causing the vulnerability such
+// as JavaScript sources, image, audio files, etc.
+message ViolatingResource {
+  // The MIME type of this resource.
+  string content_type = 1;
+
+  // URL of this violating resource.
+  string resource_url = 2;
+}
+
+// Information about vulnerable request parameters.
+message VulnerableParameters {
+  // The vulnerable parameter names.
+  repeated string parameter_names = 1;
+}
+
+// Information reported for an XSS.
+message Xss {
+  // Stack traces leading to the point where the XSS occurred.
+  repeated string stack_traces = 1;
+
+  // An error message generated by a javascript breakage.
+  string error_message = 2;
+}
diff --git a/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/finding_type_stats.proto b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/finding_type_stats.proto
new file mode 100644
index 000000000000..6b324482b123
--- /dev/null
+++ b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/finding_type_stats.proto
@@ -0,0 +1,38 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.websecurityscanner.v1alpha;
+
+import "google/api/annotations.proto";
+import "google/cloud/websecurityscanner/v1alpha/finding.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha;websecurityscanner";
+option java_multiple_files = true;
+option java_outer_classname = "FindingTypeStatsProto";
+option java_package = "com.google.cloud.websecurityscanner.v1alpha";
+
+
+// A FindingTypeStats resource represents stats regarding a specific FindingType
+// of Findings under a given ScanRun.
+message FindingTypeStats {
+  // Output only.
+  // The finding type associated with the stats.
+  Finding.FindingType finding_type = 1;
+
+  // Output only.
+  // The count of findings belonging to this finding type.
+  int32 finding_count = 2;
+}
diff --git a/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/scan_config.proto b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/scan_config.proto
new file mode 100644
index 000000000000..ffebe6fd71f5
--- /dev/null
+++ b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/scan_config.proto
@@ -0,0 +1,150 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.websecurityscanner.v1alpha;
+
+import "google/api/annotations.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha;websecurityscanner";
+option java_multiple_files = true;
+option java_outer_classname = "ScanConfigProto";
+option java_package = "com.google.cloud.websecurityscanner.v1alpha";
+
+
+// A ScanConfig resource contains the configurations to launch a scan.
+message ScanConfig {
+  // Scan authentication configuration.
+  message Authentication {
+    // Describes authentication configuration that uses a Google account.
+    message GoogleAccount {
+      // Required.
+      // The user name of the Google account.
+      string username = 1;
+
+      // Input only.
+      // Required.
+      // The password of the Google account. The credential is stored encrypted
+      // and not returned in any response.
+      string password = 2;
+    }
+
+    // Describes authentication configuration that uses a custom account.
+    message CustomAccount {
+      // Required.
+      // The user name of the custom account.
+      string username = 1;
+
+      // Input only.
+      // Required.
+      // The password of the custom account. The credential is stored encrypted
+      // and not returned in any response.
+      string password = 2;
+
+      // Required.
+      // The login form URL of the website.
+      string login_url = 3;
+    }
+
+    // Required.
+    // Authentication configuration
+    oneof authentication {
+      // Authentication using a Google account.
+      GoogleAccount google_account = 1;
+
+      // Authentication using a custom account.
+      CustomAccount custom_account = 2;
+    }
+  }
+
+  // Scan schedule configuration.
+  message Schedule {
+    // A timestamp indicates when the next run will be scheduled. The value is
+    // refreshed by the server after each run. If unspecified, it will default
+    // to current server time, which means the scan will be scheduled to start
+    // immediately.
+    google.protobuf.Timestamp schedule_time = 1;
+
+    // Required.
+    // The duration of time between executions in days.
+    int32 interval_duration_days = 2;
+  }
+
+  // Type of user agents used for scanning.
+  enum UserAgent {
+    // The user agent is unknown. Service will default to CHROME_LINUX.
+    USER_AGENT_UNSPECIFIED = 0;
+
+    // Chrome on Linux. This is the service default if unspecified.
+    CHROME_LINUX = 1;
+
+    // Chrome on Android.
+    CHROME_ANDROID = 2;
+
+    // Safari on IPhone.
+    SAFARI_IPHONE = 3;
+  }
+
+  // Cloud platforms supported by Cloud Web Security Scanner.
+  enum TargetPlatform {
+    // The target platform is unknown. Requests with this enum value will be
+    // rejected with INVALID_ARGUMENT error.
+    TARGET_PLATFORM_UNSPECIFIED = 0;
+
+    // Google App Engine service.
+    APP_ENGINE = 1;
+
+    // Google Compute Engine service.
+    COMPUTE = 2;
+  }
+
+  // The resource name of the ScanConfig. The name follows the format of
+  // 'projects/{projectId}/scanConfigs/{scanConfigId}'. The ScanConfig IDs are
+  // generated by the system.
+  string name = 1;
+
+  // Required.
+  // The user provided display name of the ScanConfig.
+  string display_name = 2;
+
+  // The maximum QPS during scanning. A valid value ranges from 5 to 20
+  // inclusively. If the field is unspecified or its value is set 0, server will
+  // default to 15. Other values outside of [5, 20] range will be rejected with
+  // INVALID_ARGUMENT error.
+  int32 max_qps = 3;
+
+  // Required.
+  // The starting URLs from which the scanner finds site pages.
+  repeated string starting_urls = 4;
+
+  // The authentication configuration. If specified, service will use the
+  // authentication configuration during scanning.
+  Authentication authentication = 5;
+
+  // The user agent used during scanning.
+  UserAgent user_agent = 6;
+
+  // The blacklist URL patterns as described in
+  // https://cloud.google.com/security-scanner/docs/excluded-urls
+  repeated string blacklist_patterns = 7;
+
+  // The schedule of the ScanConfig.
+  Schedule schedule = 8;
+
+  // Set of Cloud Platforms targeted by the scan. If empty, APP_ENGINE will be
+  // used as a default.
+  repeated TargetPlatform target_platforms = 9;
+}
diff --git a/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/scan_run.proto b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/scan_run.proto
new file mode 100644
index 000000000000..13b7e7578a87
--- /dev/null
+++ b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/scan_run.proto
@@ -0,0 +1,108 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.websecurityscanner.v1alpha;
+
+import "google/api/annotations.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha;websecurityscanner";
+option java_multiple_files = true;
+option java_outer_classname = "ScanRunProto";
+option java_package = "com.google.cloud.websecurityscanner.v1alpha";
+
+
+// A ScanRun is a output-only resource representing an actual run of the scan.
+message ScanRun {
+  // Types of ScanRun execution state.
+  enum ExecutionState {
+    // Represents an invalid state caused by internal server error. This value
+    // should never be returned.
+    EXECUTION_STATE_UNSPECIFIED = 0;
+
+    // The scan is waiting in the queue.
+    QUEUED = 1;
+
+    // The scan is in progress.
+    SCANNING = 2;
+
+    // The scan is either finished or stopped by user.
+    FINISHED = 3;
+  }
+
+  // Types of ScanRun result state.
+  enum ResultState {
+    // Default value. This value is returned when the ScanRun is not yet
+    // finished.
+    RESULT_STATE_UNSPECIFIED = 0;
+
+    // The scan finished without errors.
+    SUCCESS = 1;
+
+    // The scan finished with errors.
+    ERROR = 2;
+
+    // The scan was terminated by user.
+    KILLED = 3;
+  }
+
+  // Output only.
+  // The resource name of the ScanRun. The name follows the format of
+  // 'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.
+  // The ScanRun IDs are generated by the system.
+  string name = 1;
+
+  // Output only.
+  // The execution state of the ScanRun.
+  ExecutionState execution_state = 2;
+
+  // Output only.
+  // The result state of the ScanRun. This field is only available after the
+  // execution state reaches "FINISHED".
+  ResultState result_state = 3;
+
+  // Output only.
+  // The time at which the ScanRun started.
+  google.protobuf.Timestamp start_time = 4;
+
+  // Output only.
+  // The time at which the ScanRun reached termination state - that the ScanRun
+  // is either finished or stopped by user.
+  google.protobuf.Timestamp end_time = 5;
+
+  // Output only.
+  // The number of URLs crawled during this ScanRun. If the scan is in progress,
+  // the value represents the number of URLs crawled up to now.
+  int64 urls_crawled_count = 6;
+
+  // Output only.
+  // The number of URLs tested during this ScanRun. If the scan is in progress,
+  // the value represents the number of URLs tested up to now. The number of
+  // URLs tested is usually larger than the number URLS crawled because
+  // typically a crawled URL is tested with multiple test payloads.
+  int64 urls_tested_count = 7;
+
+  // Output only.
+  // Whether the scan run has found any vulnerabilities.
+  bool has_vulnerabilities = 8;
+
+  // Output only.
+  // The percentage of total completion ranging from 0 to 100.
+  // If the scan is in queue, the value is 0.
+  // If the scan is running, the value ranges from 0 to 100.
+  // If the scan is finished, the value is 100.
+  int32 progress_percent = 9;
+}
diff --git a/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/web_security_scanner.proto b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/web_security_scanner.proto
new file mode 100644
index 000000000000..b23375359eb9
--- /dev/null
+++ b/websecurityscanner/google/cloud/websecurityscanner_v1alpha/proto/web_security_scanner.proto
@@ -0,0 +1,346 @@
+// Copyright 2018 Google Inc.
+//
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.websecurityscanner.v1alpha;
+
+import "google/api/annotations.proto";
+import "google/cloud/websecurityscanner/v1alpha/crawled_url.proto";
+import "google/cloud/websecurityscanner/v1alpha/finding.proto";
+import "google/cloud/websecurityscanner/v1alpha/finding_type_stats.proto";
+import "google/cloud/websecurityscanner/v1alpha/scan_config.proto";
+import "google/cloud/websecurityscanner/v1alpha/scan_run.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha;websecurityscanner";
+option java_multiple_files = true;
+option java_outer_classname = "WebSecurityScannerProto";
+option java_package = "com.google.cloud.websecurityscanner.v1alpha";
+
+
+// Cloud Web Security Scanner Service identifies security vulnerabilities in web
+// applications hosted on Google Cloud Platform. It crawls your application, and
+// attempts to exercise as many user inputs and event handlers as possible.
+service WebSecurityScanner {
+  // Creates a new ScanConfig.
+  rpc CreateScanConfig(CreateScanConfigRequest) returns (ScanConfig) {
+    option (google.api.http) = {
+      post: "/v1alpha/{parent=projects/*}/scanConfigs"
+      body: "scan_config"
+    };
+  }
+
+  // Deletes an existing ScanConfig and its child resources.
+  rpc DeleteScanConfig(DeleteScanConfigRequest) returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete: "/v1alpha/{name=projects/*/scanConfigs/*}"
+    };
+  }
+
+  // Gets a ScanConfig.
+  rpc GetScanConfig(GetScanConfigRequest) returns (ScanConfig) {
+    option (google.api.http) = {
+      get: "/v1alpha/{name=projects/*/scanConfigs/*}"
+    };
+  }
+
+  // Lists ScanConfigs under a given project.
+  rpc ListScanConfigs(ListScanConfigsRequest) returns (ListScanConfigsResponse) {
+    option (google.api.http) = {
+      get: "/v1alpha/{parent=projects/*}/scanConfigs"
+    };
+  }
+
+  // Updates a ScanConfig. This method support partial update of a ScanConfig.
+  rpc UpdateScanConfig(UpdateScanConfigRequest) returns (ScanConfig) {
+    option (google.api.http) = {
+      patch: "/v1alpha/{scan_config.name=projects/*/scanConfigs/*}"
+      body: "scan_config"
+    };
+  }
+
+  // Start a ScanRun according to the given ScanConfig.
+  rpc StartScanRun(StartScanRunRequest) returns (ScanRun) {
+    option (google.api.http) = {
+      post: "/v1alpha/{name=projects/*/scanConfigs/*}:start"
+      body: "*"
+    };
+  }
+
+  // Gets a ScanRun.
+  rpc GetScanRun(GetScanRunRequest) returns (ScanRun) {
+    option (google.api.http) = {
+      get: "/v1alpha/{name=projects/*/scanConfigs/*/scanRuns/*}"
+    };
+  }
+
+  // Lists ScanRuns under a given ScanConfig, in descending order of ScanRun
+  // stop time.
+  rpc ListScanRuns(ListScanRunsRequest) returns (ListScanRunsResponse) {
+    option (google.api.http) = {
+      get: "/v1alpha/{parent=projects/*/scanConfigs/*}/scanRuns"
+    };
+  }
+
+  // Stops a ScanRun. The stopped ScanRun is returned.
+  rpc StopScanRun(StopScanRunRequest) returns (ScanRun) {
+    option (google.api.http) = {
+      post: "/v1alpha/{name=projects/*/scanConfigs/*/scanRuns/*}:stop"
+      body: "*"
+    };
+  }
+
+  // List CrawledUrls under a given ScanRun.
+  rpc ListCrawledUrls(ListCrawledUrlsRequest) returns (ListCrawledUrlsResponse) {
+    option (google.api.http) = {
+      get: "/v1alpha/{parent=projects/*/scanConfigs/*/scanRuns/*}/crawledUrls"
+    };
+  }
+
+  // Gets a Finding.
+  rpc GetFinding(GetFindingRequest) returns (Finding) {
+    option (google.api.http) = {
+      get: "/v1alpha/{name=projects/*/scanConfigs/*/scanRuns/*/findings/*}"
+    };
+  }
+
+  // List Findings under a given ScanRun.
+  rpc ListFindings(ListFindingsRequest) returns (ListFindingsResponse) {
+    option (google.api.http) = {
+      get: "/v1alpha/{parent=projects/*/scanConfigs/*/scanRuns/*}/findings"
+    };
+  }
+
+  // List all FindingTypeStats under a given ScanRun.
+  rpc ListFindingTypeStats(ListFindingTypeStatsRequest) returns (ListFindingTypeStatsResponse) {
+    option (google.api.http) = {
+      get: "/v1alpha/{parent=projects/*/scanConfigs/*/scanRuns/*}/findingTypeStats"
+    };
+  }
+}
+
+// Request for the `CreateScanConfig` method.
+message CreateScanConfigRequest {
+  // Required.
+  // The parent resource name where the scan is created, which should be a
+  // project resource name in the format 'projects/{projectId}'.
+  string parent = 1;
+
+  // Required.
+  // The ScanConfig to be created.
+  ScanConfig scan_config = 2;
+}
+
+// Request for the `DeleteScanConfig` method.
+message DeleteScanConfigRequest {
+  // Required.
+  // The resource name of the ScanConfig to be deleted. The name follows the
+  // format of 'projects/{projectId}/scanConfigs/{scanConfigId}'.
+  string name = 1;
+}
+
+// Request for the `GetScanConfig` method.
+message GetScanConfigRequest {
+  // Required.
+  // The resource name of the ScanConfig to be returned. The name follows the
+  // format of 'projects/{projectId}/scanConfigs/{scanConfigId}'.
+  string name = 1;
+}
+
+// Request for the `ListScanConfigs` method.
+message ListScanConfigsRequest {
+  // Required.
+  // The parent resource name, which should be a project resource name in the
+  // format 'projects/{projectId}'.
+  string parent = 1;
+
+  // A token identifying a page of results to be returned. This should be a
+  // `next_page_token` value returned from a previous List request.
+  // If unspecified, the first page of results is returned.
+  string page_token = 2;
+
+  // The maximum number of ScanConfigs to return, can be limited by server.
+  // If not specified or not positive, the implementation will select a
+  // reasonable value.
+  int32 page_size = 3;
+}
+
+// Request for the `UpdateScanConfigRequest` method.
+message UpdateScanConfigRequest {
+  // Required.
+  // The ScanConfig to be updated. The name field must be set to identify the
+  // resource to be updated. The values of fields not covered by the mask
+  // will be ignored.
+  ScanConfig scan_config = 2;
+
+  // Required.
+  // The update mask applies to the resource. For the `FieldMask` definition,
+  // see
+  // https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask
+  google.protobuf.FieldMask update_mask = 3;
+}
+
+// Response for the `ListScanConfigs` method.
+message ListScanConfigsResponse {
+  // The list of ScanConfigs returned.
+  repeated ScanConfig scan_configs = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no
+  // more results in the list.
+  string next_page_token = 2;
+}
+
+// Request for the `StartScanRun` method.
+message StartScanRunRequest {
+  // Required.
+  // The resource name of the ScanConfig to be used. The name follows the
+  // format of 'projects/{projectId}/scanConfigs/{scanConfigId}'.
+  string name = 1;
+}
+
+// Request for the `GetScanRun` method.
+message GetScanRunRequest {
+  // Required.
+  // The resource name of the ScanRun to be returned. The name follows the
+  // format of
+  // 'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.
+  string name = 1;
+}
+
+// Request for the `ListScanRuns` method.
+message ListScanRunsRequest {
+  // Required.
+  // The parent resource name, which should be a scan resource name in the
+  // format 'projects/{projectId}/scanConfigs/{scanConfigId}'.
+  string parent = 1;
+
+  // A token identifying a page of results to be returned. This should be a
+  // `next_page_token` value returned from a previous List request.
+  // If unspecified, the first page of results is returned.
+  string page_token = 2;
+
+  // The maximum number of ScanRuns to return, can be limited by server.
+  // If not specified or not positive, the implementation will select a
+  // reasonable value.
+  int32 page_size = 3;
+}
+
+// Response for the `ListScanRuns` method.
+message ListScanRunsResponse {
+  // The list of ScanRuns returned.
+  repeated ScanRun scan_runs = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no
+  // more results in the list.
+  string next_page_token = 2;
+}
+
+// Request for the `StopScanRun` method.
+message StopScanRunRequest {
+  // Required.
+  // The resource name of the ScanRun to be stopped. The name follows the
+  // format of
+  // 'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.
+  string name = 1;
+}
+
+// Request for the `ListCrawledUrls` method.
+message ListCrawledUrlsRequest {
+  // Required.
+  // The parent resource name, which should be a scan run resource name in the
+  // format
+  // 'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.
+  string parent = 1;
+
+  // A token identifying a page of results to be returned. This should be a
+  // `next_page_token` value returned from a previous List request.
+  // If unspecified, the first page of results is returned.
+  string page_token = 2;
+
+  // The maximum number of CrawledUrls to return, can be limited by server.
+  // If not specified or not positive, the implementation will select a
+  // reasonable value.
+  int32 page_size = 3;
+}
+
+// Response for the `ListCrawledUrls` method.
+message ListCrawledUrlsResponse {
+  // The list of CrawledUrls returned.
+  repeated CrawledUrl crawled_urls = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no
+  // more results in the list.
+  string next_page_token = 2;
+}
+
+// Request for the `GetFinding` method.
+message GetFindingRequest {
+  // Required.
+  // The resource name of the Finding to be returned. The name follows the
+  // format of
+  // 'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}/findings/{findingId}'.
+  string name = 1;
+}
+
+// Request for the `ListFindings` method.
+message ListFindingsRequest {
+  // Required.
+  // The parent resource name, which should be a scan run resource name in the
+  // format
+  // 'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.
+  string parent = 1;
+
+  // The filter expression. The expression must be in the format: <field>
+  // <operator> <value>.
+  // Supported field: 'finding_type'.
+  // Supported operator: '='.
+  string filter = 2;
+
+  // A token identifying a page of results to be returned. This should be a
+  // `next_page_token` value returned from a previous List request.
+  // If unspecified, the first page of results is returned.
+  string page_token = 3;
+
+  // The maximum number of Findings to return, can be limited by server.
+  // If not specified or not positive, the implementation will select a
+  // reasonable value.
+  int32 page_size = 4;
+}
+
+// Response for the `ListFindings` method.
+message ListFindingsResponse {
+  // The list of Findings returned.
+  repeated Finding findings = 1;
+
+  // Token to retrieve the next page of results, or empty if there are no
+  // more results in the list.
+  string next_page_token = 2;
+}
+
+// Request for the `ListFindingTypeStats` method.
+message ListFindingTypeStatsRequest {
+  // Required.
+  // The parent resource name, which should be a scan run resource name in the
+  // format
+  // 'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.
+  string parent = 1;
+}
+
+// Response for the `ListFindingTypeStats` method.
+message ListFindingTypeStatsResponse {
+  // The list of FindingTypeStats returned.
+  repeated FindingTypeStats finding_type_stats = 1;
+}
diff --git a/websecurityscanner/synth.metadata b/websecurityscanner/synth.metadata
index 7452e8ad0a62..bcc9af3284d4 100644
--- a/websecurityscanner/synth.metadata
+++ b/websecurityscanner/synth.metadata
@@ -1,19 +1,19 @@
 {
-  "updateTime": "2019-01-17T13:34:15.690044Z",
+  "updateTime": "2019-01-24T17:51:24.573141Z",
   "sources": [
     {
       "generator": {
         "name": "artman",
-        "version": "0.16.6",
-        "dockerImage": "googleapis/artman@sha256:12722f2ca3fbc3b53cc6aa5f0e569d7d221b46bd876a2136497089dec5e3634e"
+        "version": "0.16.7",
+        "dockerImage": "googleapis/artman@sha256:d6c8ced606eb49973ca95d2af7c55a681acc042db0f87d135968349e7bf6dd80"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "0ac60e21a1aa86c07c1836865b35308ba8178b05",
-        "internalRef": "229626798"
+        "sha": "9aac88a22468b1e291937f55fa1ef237adfdc63e",
+        "internalRef": "230568136"
       }
     },
     {
diff --git a/websecurityscanner/synth.py b/websecurityscanner/synth.py
index 7242b66a3110..6ad4ec70c9c3 100644
--- a/websecurityscanner/synth.py
+++ b/websecurityscanner/synth.py
@@ -28,6 +28,7 @@
     config_path="/google/cloud/websecurityscanner"
     "/artman_websecurityscanner_v1alpha.yaml",
     artman_output_name="websecurityscanner-v1alpha",
+    include_protos=True,
 )
 
 s.move(library / "google/cloud/websecurityscanner_v1alpha/proto")
