// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.shopping.merchant.products.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/shopping/merchant/products/v1/products_common.proto";
import "google/shopping/type/types.proto";

option csharp_namespace = "Google.Shopping.Merchant.Products.V1";
option go_package = "cloud.google.com/go/shopping/merchant/products/apiv1/productspb;productspb";
option java_multiple_files = true;
option java_outer_classname = "ProductsProto";
option java_package = "com.google.shopping.merchant.products.v1";
option php_namespace = "Google\\Shopping\\Merchant\\Products\\V1";
option ruby_package = "Google::Shopping::Merchant::Products::V1";
option (google.api.resource_definition) = {
  type: "merchantapi.googleapis.com/Account"
  pattern: "accounts/{account}"
};

// Service to use Product resource.
service ProductsService {
  option (google.api.default_host) = "merchantapi.googleapis.com";
  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/content";

  // Retrieves the processed product from your Merchant Center account.
  //
  // After inserting, updating, or deleting a product input, it may take several
  // minutes before the updated final product can be retrieved.
  rpc GetProduct(GetProductRequest) returns (Product) {
    option (google.api.http) = {
      get: "/products/v1/{name=accounts/*/products/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists the processed products in your Merchant Center account. The response
  // might contain fewer items than specified by `pageSize`. Rely on `pageToken`
  // to determine if there are more items to be requested.
  //
  // After inserting, updating, or deleting a product input, it may take several
  // minutes before the updated processed product can be retrieved.
  rpc ListProducts(ListProductsRequest) returns (ListProductsResponse) {
    option (google.api.http) = {
      get: "/products/v1/{parent=accounts/*}/products"
    };
    option (google.api.method_signature) = "parent";
  }
}

// The processed product, built from multiple [product
// inputs][google.shopping.merchant.products.v1main.ProductInput]
// after applying rules and supplemental data sources. This processed product
// matches what is shown in your Merchant Center account. Each product is built
// from exactly one primary data source product input, and multiple supplemental
// data source inputs. After inserting, updating, or deleting a product input,
// it may take several minutes before the updated processed product can be
// retrieved.
//
// All fields in the processed product and its sub-messages match the name of
// their corresponding attribute in the [Product data
// specification](https://support.google.com/merchants/answer/7052112) with some
// exceptions.
message Product {
  option (google.api.resource) = {
    type: "merchantapi.googleapis.com/Product"
    pattern: "accounts/{account}/products/{product}"
  };

  // The name of the product.
  // Format:
  // `accounts/{account}/products/{product}` where the last
  // section `product` consists of:
  // `content_language~feed_label~offer_id`
  // example for product name is `accounts/123/products/en~US~sku123`. A legacy
  // local product name would be `accounts/123/products/local~en~US~sku123`.
  // Note: For calls to the v1beta version, the `product` section consists
  // of: `channel~content_language~feed_label~offer_id`, for example:
  // `accounts/123/products/online~en~US~sku123`.
  string name = 1;

  // Output only. The **unpadded base64url encoded name** of the product.
  // Format:
  // `accounts/{account}/products/{product}` where the last
  // section `product` is the unpadded base64url encoding of the
  // `content_language~feed_label~offer_id` name.
  // Example: `accounts/123/products/ZW5-VVN-c2t1LzEyMw` for the decoded product
  // name `accounts/123/products/en~US~sku/123`. This field can be used directly
  // as input to the API methods that require the product name to be encoded if
  // it contains special characters, for example
  // [`GetProduct`](https://developers.google.com/merchant/api/reference/rest/products_v1/accounts.products/get).
  string base64_encoded_name = 15 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Determines whether the product is **only** targeting
  // local destinations and whether the product name should be distinguished
  // with a `local~` prefix. For example,
  // `accounts/123/products/local~en~US~sku123`.
  bool legacy_local = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Your unique identifier for the product. This is the same for
  // the product input and processed product. Leading and trailing whitespaces
  // are stripped and multiple whitespaces are replaced by a single whitespace
  // upon submission. See the [product data
  // specification](https://support.google.com/merchants/answer/188494#id) for
  // details.
  string offer_id = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The two-letter [ISO
  // 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the
  // product.
  string content_language = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The feed label lets you categorize and identify your products.
  // The maximum allowed characters is 20 and the supported characters are`A-Z`,
  // `0-9`, hyphen and underscore. The feed label must not include any spaces.
  // For more information, see [Using feed
  // labels](//support.google.com/merchants/answer/14994087)
  string feed_label = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The primary data source of the product.
  string data_source = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Represents the existing version (freshness) of the product,
  // which can be used to preserve the right order when multiple updates are
  // done at the same time.
  //
  // If set, the insertion is prevented when version number is lower than
  // the current version number of the existing product. Re-insertion (for
  // example, product refresh after 30 days) can be performed with the current
  // `version_number`.
  //
  // Only supported for insertions into primary data sources.
  //
  // If the operation is prevented, the aborted exception will be
  // thrown.
  optional int64 version_number = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A list of strongly-typed product attributes.
  ProductAttributes product_attributes = 13
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A list of custom (merchant-provided) attributes. It can also
  // be used to submit any attribute of the data specification in its generic
  // form (for example,
  // `{ "name": "size type", "value": "regular" }`).
  // This is useful for submitting attributes not explicitly exposed by the
  // API, such as additional attributes used for Buy on Google.
  repeated google.shopping.type.CustomAttribute custom_attributes = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The status of a product, data validation issues, that is,
  // information about a product computed asynchronously.
  ProductStatus product_status = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The automated discounts information for the product.
  AutomatedDiscounts automated_discounts = 12
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Request message for the GetProduct method.
message GetProductRequest {
  // Required. The name of the product.
  // Format: `accounts/{account}/products/{product}`
  //
  // The `{product}` segment is a unique identifier for the product.
  // This identifier must be unique within a merchant account and generally
  // follows the structure: `content_language~feed_label~offer_id`. Example:
  // `en~US~sku123` For legacy local products, the structure is:
  // `local~content_language~feed_label~offer_id`. Example: `local~en~US~sku123`
  //
  // The format of the `{product}` segment in the URL is automatically detected
  // by the server, supporting two options:
  //
  // 1.  **Encoded Format**: The `{product}` segment is an unpadded base64url
  //     encoded string (RFC 4648 Section 5). The decoded string must result
  //     in the `content_language~feed_label~offer_id` structure. This encoding
  //     MUST be used if any part of the product identifier (like `offer_id`)
  //     contains characters such as `/`, `%`, or `~`.
  //     *   Example: To represent the product ID `en~US~sku/123`, the
  //         `{product}` segment must be the unpadded base64url encoding of this
  //         string, which is `ZW5-VVN-c2t1LzEyMw`. The full resource name
  //         for the product would be
  //         `accounts/123/products/ZW5-VVN-c2t1LzEyMw`.
  //
  // 2.  **Plain Format**: The `{product}` segment is the tilde-separated string
  //     `content_language~feed_label~offer_id`. This format is suitable only
  //     when `content_language`, `feed_label`, and `offer_id` do not contain
  //     URL-problematic characters like `/`, `%`, or `~`.
  //
  // We recommend using the **Encoded Format** for all product IDs to ensure
  // correct parsing, especially those containing special characters. The
  // presence of tilde (`~`) characters in the `{product}` segment is used to
  // differentiate between the two formats.
  //
  // Note: For calls to the v1beta version, the plain format is
  //     `channel~content_language~feed_label~offer_id`, for example:
  //     `accounts/123/products/online~en~US~sku123`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "merchantapi.googleapis.com/Product"
    }
  ];
}

// Request message for the ListProducts method.
message ListProductsRequest {
  // Required. The account to list processed products for.
  // Format: `accounts/{account}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "merchantapi.googleapis.com/Product"
    }
  ];

  // The maximum number of products to return. The service may return fewer than
  // this value.
  // The maximum value is 1000; values above 1000 will be coerced to 1000.
  // If unspecified, the default page size of 25 products will be returned.
  int32 page_size = 2;

  // A page token, received from a previous `ListProducts` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListProducts` must
  // match the call that provided the page token.
  string page_token = 3;
}

// Response message for the ListProducts method.
message ListProductsResponse {
  // The processed products from the specified account. These are your processed
  // products after applying rules and supplemental data sources.
  repeated Product products = 1;

  // A token, which can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}
