// 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.ads.googleads.v21.services;

import "google/ads/googleads/v21/common/criteria.proto";
import "google/ads/googleads/v21/common/dates.proto";
import "google/ads/googleads/v21/common/keyword_plan_common.proto";
import "google/ads/googleads/v21/enums/keyword_match_type.proto";
import "google/ads/googleads/v21/enums/keyword_plan_keyword_annotation.proto";
import "google/ads/googleads/v21/enums/keyword_plan_network.proto";
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";

option csharp_namespace = "Google.Ads.GoogleAds.V21.Services";
option go_package = "google.golang.org/genproto/googleapis/ads/googleads/v21/services;services";
option java_multiple_files = true;
option java_outer_classname = "KeywordPlanIdeaServiceProto";
option java_package = "com.google.ads.googleads.v21.services";
option objc_class_prefix = "GAA";
option php_namespace = "Google\\Ads\\GoogleAds\\V21\\Services";
option ruby_package = "Google::Ads::GoogleAds::V21::Services";

// Proto file describing the keyword plan idea service.

// Service to generate keyword ideas.
service KeywordPlanIdeaService {
  option (google.api.default_host) = "googleads.googleapis.com";
  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/adwords";

  // Returns a list of keyword ideas.
  //
  // List of thrown errors:
  //   [AuthenticationError]()
  //   [AuthorizationError]()
  //   [CollectionSizeError]()
  //   [HeaderError]()
  //   [InternalError]()
  //   [KeywordPlanIdeaError]()
  //   [QuotaError]()
  //   [RequestError]()
  rpc GenerateKeywordIdeas(GenerateKeywordIdeasRequest)
      returns (GenerateKeywordIdeaResponse) {
    option (google.api.http) = {
      post: "/v21/customers/{customer_id=*}:generateKeywordIdeas"
      body: "*"
    };
  }

  // Returns a list of keyword historical metrics.
  //
  // List of thrown errors:
  //   [AuthenticationError]()
  //   [AuthorizationError]()
  //   [CollectionSizeError]()
  //   [HeaderError]()
  //   [InternalError]()
  //   [QuotaError]()
  //   [RequestError]()
  rpc GenerateKeywordHistoricalMetrics(GenerateKeywordHistoricalMetricsRequest)
      returns (GenerateKeywordHistoricalMetricsResponse) {
    option (google.api.http) = {
      post: "/v21/customers/{customer_id=*}:generateKeywordHistoricalMetrics"
      body: "*"
    };
  }

  // Returns a list of suggested AdGroups and suggested modifications
  // (text, match type) for the given keywords.
  //
  // List of thrown errors:
  //   [AuthenticationError]()
  //   [AuthorizationError]()
  //   [CollectionSizeError]()
  //   [HeaderError]()
  //   [InternalError]()
  //   [QuotaError]()
  //   [RequestError]()
  rpc GenerateAdGroupThemes(GenerateAdGroupThemesRequest)
      returns (GenerateAdGroupThemesResponse) {
    option (google.api.http) = {
      post: "/v21/customers/{customer_id=*}:generateAdGroupThemes"
      body: "*"
    };
    option (google.api.method_signature) = "customer_id,keywords,ad_groups";
  }

  // Returns metrics (such as impressions, clicks, total cost) of a keyword
  // forecast for the given campaign.
  //
  // List of thrown errors:
  //   [AuthenticationError]()
  //   [AuthorizationError]()
  //   [CollectionSizeError]()
  //   [HeaderError]()
  //   [InternalError]()
  //   [QuotaError]()
  //   [RequestError]()
  rpc GenerateKeywordForecastMetrics(GenerateKeywordForecastMetricsRequest)
      returns (GenerateKeywordForecastMetricsResponse) {
    option (google.api.http) = {
      post: "/v21/customers/{customer_id=*}:generateKeywordForecastMetrics"
      body: "*"
    };
    option (google.api.method_signature) = "campaign";
  }
}

// Request message for
// [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v21.services.KeywordPlanIdeaService.GenerateKeywordIdeas].
message GenerateKeywordIdeasRequest {
  // The ID of the customer with the recommendation.
  string customer_id = 1;

  // The resource name of the language to target.
  // Each keyword belongs to some set of languages; a keyword is included if
  // language is one of its languages.
  // If not set, all keywords will be included.
  optional string language = 14;

  // The resource names of the location to target. Maximum is 10.
  // An empty list MAY be used to specify all targeting geos.
  repeated string geo_target_constants = 15;

  // If true, adult keywords will be included in response.
  // The default value is false.
  bool include_adult_keywords = 10;

  // Token of the page to retrieve. If not specified, the first
  // page of results will be returned. To request next page of results use the
  // value obtained from `next_page_token` in the previous response.
  // The request fields must match across pages.
  string page_token = 12;

  // Number of results to retrieve in a single page.
  // A maximum of 10,000 results may be returned, if the page_size
  // exceeds this, it is ignored.
  // If unspecified, at most 10,000 results will be returned.
  // The server may decide to further limit the number of returned resources.
  // If the response contains fewer than 10,000 results it may not be assumed
  // as last page of results.
  int32 page_size = 13;

  // Targeting network.
  // If not set, Google Search And Partners Network will be used.
  google.ads.googleads.v21.enums.KeywordPlanNetworkEnum.KeywordPlanNetwork
      keyword_plan_network = 9;

  // The keyword annotations to include in response.
  repeated google.ads.googleads.v21.enums.KeywordPlanKeywordAnnotationEnum
      .KeywordPlanKeywordAnnotation keyword_annotation = 17;

  // The aggregate fields to include in response.
  google.ads.googleads.v21.common.KeywordPlanAggregateMetrics
      aggregate_metrics = 16;

  // The options for historical metrics data.
  google.ads.googleads.v21.common.HistoricalMetricsOptions
      historical_metrics_options = 18;

  // The type of seed to generate keyword ideas.
  oneof seed {
    // A Keyword and a specific Url to generate ideas from
    // for example, cars, www.example.com/cars.
    KeywordAndUrlSeed keyword_and_url_seed = 2;

    // A Keyword or phrase to generate ideas from, for example, cars.
    KeywordSeed keyword_seed = 3;

    // A specific url to generate ideas from, for example, www.example.com/cars.
    UrlSeed url_seed = 5;

    // The site to generate ideas from, for example, www.example.com.
    SiteSeed site_seed = 11;
  }
}

// Keyword And Url Seed
message KeywordAndUrlSeed {
  // The URL to crawl in order to generate keyword ideas.
  optional string url = 3;

  // Requires at least one keyword and no more than 20 keywords.
  repeated string keywords = 4;
}

// Keyword Seed
message KeywordSeed {
  // Requires at least one keyword and no more than 20 keywords.
  repeated string keywords = 2;
}

// Site Seed
message SiteSeed {
  // The domain name of the site. If the customer requesting the ideas doesn't
  // own the site provided only public information is returned.
  optional string site = 2;
}

// Url Seed
message UrlSeed {
  // The URL to crawl in order to generate keyword ideas.
  optional string url = 2;
}

// Response message for
// [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v21.services.KeywordPlanIdeaService.GenerateKeywordIdeas].
message GenerateKeywordIdeaResponse {
  // Results of generating keyword ideas.
  repeated GenerateKeywordIdeaResult results = 1;

  // The aggregate metrics for all keyword ideas.
  google.ads.googleads.v21.common.KeywordPlanAggregateMetricResults
      aggregate_metric_results = 4;

  // Pagination token used to retrieve the next page of results.
  // Pass the content of this string as the `page_token` attribute of
  // the next request.
  // `next_page_token` is not returned for the last page.
  string next_page_token = 2;

  // Total number of results available.
  int64 total_size = 3;
}

// The result of generating keyword ideas.
message GenerateKeywordIdeaResult {
  // Text of the keyword idea.
  // As in Keyword Plan historical metrics, this text may not be an actual
  // keyword, but the canonical form of multiple keywords.
  // See KeywordPlanKeywordHistoricalMetrics message in KeywordPlanService.
  optional string text = 5;

  // The historical metrics for the keyword.
  google.ads.googleads.v21.common.KeywordPlanHistoricalMetrics
      keyword_idea_metrics = 3;

  // The annotations for the keyword.
  // The annotation data is only provided if requested.
  google.ads.googleads.v21.common.KeywordAnnotations keyword_annotations = 6;

  // The list of close variants from the requested keywords that
  // are combined into this GenerateKeywordIdeaResult. See
  // https://support.google.com/google-ads/answer/9342105 for the
  // definition of "close variants".
  repeated string close_variants = 7;
}

// Request message for
// [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v21.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics].
message GenerateKeywordHistoricalMetricsRequest {
  // The ID of the customer with the recommendation.
  string customer_id = 1;

  // A list of keywords to get historical metrics.
  // Not all inputs will be returned as a result of near-exact deduplication.
  // For example, if stats for "car" and "cars" are requested, only "car" will
  // be returned.
  // A maximum of 10,000 keywords can be used.
  repeated string keywords = 2;

  // The resource name of the language to target.
  // Each keyword belongs to some set of languages; a keyword is included if
  // language is one of its languages.
  // If not set, all keywords will be included.
  optional string language = 4;

  // If true, adult keywords will be included in response.
  // The default value is false.
  bool include_adult_keywords = 5;

  // The resource names of the location to target. Maximum is 10.
  // An empty list MAY be used to specify all targeting geos.
  repeated string geo_target_constants = 6;

  // Targeting network.
  // If not set, Google Search And Partners Network will be used.
  google.ads.googleads.v21.enums.KeywordPlanNetworkEnum.KeywordPlanNetwork
      keyword_plan_network = 7;

  // The aggregate fields to include in response.
  google.ads.googleads.v21.common.KeywordPlanAggregateMetrics
      aggregate_metrics = 8;

  // The options for historical metrics data.
  google.ads.googleads.v21.common.HistoricalMetricsOptions
      historical_metrics_options = 3;
}

// Response message for
// [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v21.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics].
message GenerateKeywordHistoricalMetricsResponse {
  // List of keywords and their historical metrics.
  repeated GenerateKeywordHistoricalMetricsResult results = 1;

  // The aggregate metrics for all keywords.
  google.ads.googleads.v21.common.KeywordPlanAggregateMetricResults
      aggregate_metric_results = 2;
}

// The result of generating keyword historical metrics.
message GenerateKeywordHistoricalMetricsResult {
  // The text of the query associated with one or more keywords.
  // Note that we de-dupe your keywords list, eliminating close variants
  // before returning the keywords as text. For example, if your request
  // originally contained the keywords "car" and "cars", the returned search
  // query will only contain "cars". The list of de-duped queries will be
  // included in close_variants field.
  optional string text = 1;

  // The list of close variants from the requested keywords whose stats
  // are combined into this GenerateKeywordHistoricalMetricsResult.
  repeated string close_variants = 3;

  // The historical metrics for text and its close variants
  google.ads.googleads.v21.common.KeywordPlanHistoricalMetrics keyword_metrics =
      2;
}

// Request message for
// [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v21.services.KeywordPlanIdeaService.GenerateAdGroupThemes].
message GenerateAdGroupThemesRequest {
  // Required. The ID of the customer.
  string customer_id = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. A list of keywords to group into the provided AdGroups.
  repeated string keywords = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. A list of resource names of AdGroups to group keywords into.
  //  Resource name format: `customers/{customer_id}/adGroups/{ad_group_id}`
  repeated string ad_groups = 3 [(google.api.field_behavior) = REQUIRED];
}

// Response message for
// [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v21.services.KeywordPlanIdeaService.GenerateAdGroupThemes].
message GenerateAdGroupThemesResponse {
  // A list of suggested AdGroup/keyword pairings.
  repeated AdGroupKeywordSuggestion ad_group_keyword_suggestions = 1;

  // A list of provided AdGroups that could not be used as suggestions.
  repeated UnusableAdGroup unusable_ad_groups = 2;
}

// The suggested text and AdGroup/Campaign pairing for a given keyword.
message AdGroupKeywordSuggestion {
  // The original keyword text.
  string keyword_text = 1;

  // The normalized version of keyword_text for BROAD/EXACT/PHRASE suggestions.
  string suggested_keyword_text = 2;

  // The suggested keyword match type.
  google.ads.googleads.v21.enums.KeywordMatchTypeEnum.KeywordMatchType
      suggested_match_type = 3;

  // The suggested AdGroup for the keyword.
  // Resource name format: `customers/{customer_id}/adGroups/{ad_group_id}`
  string suggested_ad_group = 4;

  // The suggested Campaign for the keyword.
  // Resource name format: `customers/{customer_id}/campaigns/{campaign_id}`
  string suggested_campaign = 5;
}

// An AdGroup/Campaign pair that could not be used as a suggestion for keywords.
//
// AdGroups may not be usable if the AdGroup
//
// * belongs to a Campaign that is not ENABLED or PAUSED
// * is itself not ENABLED
message UnusableAdGroup {
  // The AdGroup resource name.
  // Resource name format: `customers/{customer_id}/adGroups/{ad_group_id}`
  string ad_group = 1;

  // The Campaign resource name.
  // Resource name format: `customers/{customer_id}/campaigns/{campaign_id}`
  string campaign = 2;
}

// Request message for
// [KeywordPlanIdeaService.GenerateKeywordForecastMetrics][google.ads.googleads.v21.services.KeywordPlanIdeaService.GenerateKeywordForecastMetrics].
message GenerateKeywordForecastMetricsRequest {
  // The ID of the customer.
  string customer_id = 1;

  // The currency used for exchange rate conversion.
  // By default, the account currency of the customer is used.
  // Set this field only if the currency is different from the account currency.
  // The list of valid currency codes can be found at
  // https://developers.google.com/google-ads/api/data/codes-formats#currency-codes.
  optional string currency_code = 2;

  // The date range for the forecast. The start date must be in the future and
  // end date must be within 1 year from today. The reference timezone used is
  // the one of the Google Ads account belonging to the customer. If not set, a
  // default date range from next Sunday to the following Saturday will be used.
  google.ads.googleads.v21.common.DateRange forecast_period = 3;

  // Required. The campaign used in the forecast.
  CampaignToForecast campaign = 4 [(google.api.field_behavior) = REQUIRED];
}

// A campaign to do a keyword campaign forecast.
message CampaignToForecast {
  // Supported bidding strategies for new campaign forecasts.
  message CampaignBiddingStrategy {
    // Bidding strategies.
    oneof bidding_strategy {
      // Use manual CPC bidding strategy for forecasting.
      ManualCpcBiddingStrategy manual_cpc_bidding_strategy = 1;

      // Use maximize clicks bidding strategy for forecasting.
      MaximizeClicksBiddingStrategy maximize_clicks_bidding_strategy = 2;

      // Use maximize conversions bidding strategy for forecasting.
      MaximizeConversionsBiddingStrategy maximize_conversions_bidding_strategy =
          3;
    }
  }

  // The list of resource names of languages to be targeted. The resource name
  // is of the format "languageConstants/{criterion_id}". See
  // https://developers.google.com/google-ads/api/data/codes-formats#languages
  // for the list of language criterion codes.
  repeated string language_constants = 1;

  // Locations to be targeted. Locations must be unique.
  repeated CriterionBidModifier geo_modifiers = 2;

  // Required. The network used for targeting.
  google.ads.googleads.v21.enums.KeywordPlanNetworkEnum.KeywordPlanNetwork
      keyword_plan_network = 3 [(google.api.field_behavior) = REQUIRED];

  // The list of negative keywords to be used in the campaign when doing the
  // forecast.
  repeated google.ads.googleads.v21.common.KeywordInfo negative_keywords = 4;

  // Required. The bidding strategy for the campaign.
  CampaignBiddingStrategy bidding_strategy = 5
      [(google.api.field_behavior) = REQUIRED];

  // The expected conversion rate (number of conversions divided by number of
  // total clicks) as defined by the user. This value is expressed as a decimal
  // value, so an expected conversion rate of 2% should be entered as 0.02. If
  // left empty, an estimated conversion rate will be used.
  optional double conversion_rate = 6;

  // The ad groups in the new campaign to forecast.
  repeated ForecastAdGroup ad_groups = 7;
}

// An ad group that is part of a campaign to be forecasted.
message ForecastAdGroup {
  // The max cpc to use for the ad group when generating forecasted traffic.
  // This value will override the max cpc value set in the bidding strategy.
  // Only specify this field for bidding strategies that max cpc values.
  optional int64 max_cpc_bid_micros = 1;

  // Required. The list of biddable keywords to be used in the ad group when
  // doing the forecast. Requires at least one keyword.
  repeated BiddableKeyword biddable_keywords = 2
      [(google.api.field_behavior) = REQUIRED];

  // The details of the keyword. You should specify both the keyword text and
  // match type.
  repeated google.ads.googleads.v21.common.KeywordInfo negative_keywords = 3;
}

// A biddable keyword part of an ad group.
message BiddableKeyword {
  // Required. Keyword. Must have text and match type.
  google.ads.googleads.v21.common.KeywordInfo keyword = 1
      [(google.api.field_behavior) = REQUIRED];

  // A max cpc bid in micros that overrides the ad group level max cpc bid in
  // forecast simulation. This value will override the max cpc value set in the
  // bidding strategy and ad group. Only specify this field for bidding
  // strategies that support max cpc values.
  optional int64 max_cpc_bid_micros = 2;
}

// Location Criterion bid modifier.
message CriterionBidModifier {
  // The resource name of the geo location to target. The resource name is of
  // the format "geoTargetConstants/{criterion_id}".
  string geo_target_constant = 1;

  // The associated multiplier for the criterion_id. If set, this value cannot
  // be 0.
  optional double bid_modifier = 2;
}

// Manual CPC Bidding Strategy.
message ManualCpcBiddingStrategy {
  // Campaign level budget in micros. If set, a minimum value
  // is enforced for the local currency used in the campaign. An error
  // will occur showing the minimum value if this field is set too low.
  optional int64 daily_budget_micros = 1;

  // Required. A bid in micros to be applied to ad groups within the campaign
  // for a manual CPC bidding strategy.
  int64 max_cpc_bid_micros = 2 [(google.api.field_behavior) = REQUIRED];
}

// Maximize Clicks Bidding Strategy.
message MaximizeClicksBiddingStrategy {
  // Required. The daily target spend in micros to be used for estimation. A
  // minimum value is enforced for the local currency used in the campaign. An
  // error will occur showing the minimum value if this field is set too low.
  int64 daily_target_spend_micros = 1 [(google.api.field_behavior) = REQUIRED];

  // Ceiling on max CPC bids in micros.
  optional int64 max_cpc_bid_ceiling_micros = 2;
}

// Maximize Conversions Bidding Strategy.
message MaximizeConversionsBiddingStrategy {
  // Required. The daily target spend in micros to be used for estimation. This
  // value must be greater than zero.
  int64 daily_target_spend_micros = 1 [(google.api.field_behavior) = REQUIRED];
}

// Response message for
// [KeywordPlanIdeaService.GenerateKeywordForecastMetrics][google.ads.googleads.v21.services.KeywordPlanIdeaService.GenerateKeywordForecastMetrics].
message GenerateKeywordForecastMetricsResponse {
  // Results of the campaign forecast.
  optional KeywordForecastMetrics campaign_forecast_metrics = 1;
}

// The forecast metrics for the planless keyword campaign.
message KeywordForecastMetrics {
  // The total number of impressions.
  optional double impressions = 1;

  // The average click through rate. Available only if impressions > 0.
  optional double click_through_rate = 2;

  // The average cpc. Available only if clicks > 0.
  optional int64 average_cpc_micros = 3;

  // The total number of clicks.
  optional double clicks = 4;

  // The total cost.
  optional int64 cost_micros = 5;

  // Forecasted number of conversions: clicks * conversion_rate.
  optional double conversions = 6;

  // Forecasted conversion rate.
  optional double conversion_rate = 7;

  // Average cost per acquisition calculated as cost_micros / conversions.
  optional int64 average_cpa_micros = 8;
}
