[Recommendations](https://support.google.com/google-ads/answer/3416396) can improve
your campaigns in a few ways:

- Introduce new and relevant features
- Get more out of your budget with improved bids, keywords, and ads
- Increase the overall performance and efficiency of your campaigns

To increase optimization scores, you can use the
[`RecommendationService`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationService.md.txt) to retrieve
recommendations, and then apply or dismiss them accordingly. You can also
subscribe to [automatically apply](https://developers.google.com/google-ads/api/docs/recommendations.md.txt#auto-apply)
recommendations by using the `RecommendationSubscriptionService`.

## Optimization score

[Optimization score](https://support.google.com/google-ads/answer/9061546) is an
estimate of how well your Google Ads account is set to perform and is available
at the [`Customer`](https://developers.google.com/google-ads/api/reference/rpc/v26/Customer.md.txt#optimization_score) and
[`Campaign`](https://developers.google.com/google-ads/api/reference/rpc/v26/Campaign.md.txt#optimization_score) levels.

> [!NOTE]
> **Note:** If you have multiple customer accounts and want to compute the overall optimization score, calculate the weighted average across scored accounts by summing the product of each account's optimization score and optimization score weight, and dividing by the sum of the weights: `SUM(Customer.optimization_score * Customer.optimization_score_weight) /
> SUM(Customer.optimization_score_weight)`.

There are optimization-related metrics available for `customer` and `campaign`
reports:

1. The [`metrics.optimization_score_url`](https://developers.google.com/google-ads/api/fields/v26/metrics.md.txt#metrics.optimization_score_url) provides a deep link into the account to view information on the related recommendations in the Google Ads UI.
2. The [`metrics.optimization_score_uplift`](https://developers.google.com/google-ads/api/fields/v26/metrics.md.txt#metrics.optimization_score_uplift) tells how much the optimization score would increase if all related recommendations are applied. It's an estimate based on all available recommendations as a whole, not just the sum of the uplift scores for each recommendation.

To group and order the returned recommendations, you can segment both of these
metrics by recommendation type using `segments.recommendation_type` in your
query.

## Recommendation types

The following table lists the recommendation types that are supported in the
Google Ads API for retrieving, applying, and dismissing recommendations. If an account
has recommendation types in the Google Ads UI that are not supported in the API,
you can use [`metrics.optimization_score_url`](https://developers.google.com/google-ads/api/fields/v26/metrics.md.txt#metrics.optimization_score_url) to link users
directly to the Recommendations page in the Google Ads UI to review and act on
those recommendations.

#### Fully-supported [recommendation
types](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationTypeEnum.RecommendationType)

| [RecommendationType](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationTypeEnum.RecommendationType.md.txt) | Description |
|---|---|
| `CAMPAIGN_BUDGET` | Fix campaigns limited by budget |
| `KEYWORD` | Add new keywords |
| `TEXT_AD` | Add ad suggestions |
| `TARGET_CPA_OPT_IN` | Bid with Target CPA |
| `MAXIMIZE_CONVERSIONS_OPT_IN` | Bid with Maximize Conversions |
| `MAXIMIZE_CONVERSION_VALUE_OPT_IN` | Bid with Maximize Conversion Value |
| `ENHANCED_CPC_OPT_IN` | Bid with Enhanced CPC |
| `MAXIMIZE_CLICKS_OPT_IN` | Bid with Maximize Clicks |
| `OPTIMIZE_AD_ROTATION` | Use optimized ad rotations |
| `MOVE_UNUSED_BUDGET` | Move unused to constrained budgets |
| `TARGET_ROAS_OPT_IN` | Bid with Target ROAS |
| `FORECASTING_CAMPAIGN_BUDGET` | Fix campaigns that are expected to become limited by budget in the future |
| `RESPONSIVE_SEARCH_AD` | Add new responsive search ad |
| `MARGINAL_ROI_CAMPAIGN_BUDGET` | Adjust campaign budget to increase ROI |
| `USE_BROAD_MATCH_KEYWORD` | Use [broad match](https://developers.google.com/google-ads/api/reference/rpc/v26/KeywordMatchTypeEnum.KeywordMatchType.md.txt#broad) for conversion-based campaigns with automated bidding |
| `RESPONSIVE_SEARCH_AD_ASSET` | Add responsive search ad assets to an ad |
| `RESPONSIVE_SEARCH_AD_IMPROVE_AD_STRENGTH` | Improve the strength of a responsive search ad |
| `DISPLAY_EXPANSION_OPT_IN` | Update a campaign to use Display Expansion |
| `SEARCH_PARTNERS_OPT_IN` | Expand reach with Google Search partners |
| `CUSTOM_AUDIENCE_OPT_IN` | Create a custom audience |
| `IMPROVE_DEMAND_GEN_AD_STRENGTH` | Improve the strength of ads in Demand Gen campaigns |
| `UPGRADE_SMART_SHOPPING_CAMPAIGN_TO_PERFORMANCE_MAX` | Upgrade a Smart Shopping campaign to a Performance Max campaign |
| `UPGRADE_LOCAL_CAMPAIGN_TO_PERFORMANCE_MAX` | Upgrade a legacy local campaign to a Performance Max campaign |
| `SHOPPING_MIGRATE_REGULAR_SHOPPING_CAMPAIGN_OFFERS_TO_PERFORMANCE_MAX` | Migrate offers targeted by Regular Shopping Campaigns to existing Performance Max campaigns |
| `MIGRATE_DYNAMIC_SEARCH_ADS_CAMPAIGN_TO_PERFORMANCE_MAX` | Migrate Dynamic Search Ads to Performance Max campaigns |
| `PERFORMANCE_MAX_OPT_IN` | Create Performance Max campaigns in your account |
| `IMPROVE_PERFORMANCE_MAX_AD_STRENGTH` | Improve the asset group strength of a Performance Max campaign to an "Excellent" rating |
| `PERFORMANCE_MAX_FINAL_URL_OPT_IN` | Turn on Final URL expansion for your Performance Max campaigns |
| `RAISE_TARGET_CPA_BID_TOO_LOW` | Raise target CPA when it is too low and there are very few or no conversions |
| `FORECASTING_SET_TARGET_ROAS` | Raise the budget in advance of a seasonal event that is forecasted to increase traffic, and change bidding strategy from maximize conversion value to target ROAS |
| `LEAD_FORM_ASSET` | Add lead form assets to a campaign |
| `CALLOUT_ASSET` | Add callout assets to campaign or customer level |
| `SITELINK_ASSET` | Add sitelink assets to campaign or customer level |
| `CALL_ASSET` | Add call assets to campaign or customer level |
| `SHOPPING_ADD_AGE_GROUP` | Add the age group attribute to offers that are demoted because of a missing age group |
| `SHOPPING_ADD_COLOR` | Add a color to offers that are demoted because of a missing color |
| `SHOPPING_ADD_GENDER` | Add a gender to offers that are demoted because of a missing gender |
| `SHOPPING_ADD_GTIN` | Add a GTIN (Global Trade Item Number) to offers that are demoted because of a missing GTIN |
| `SHOPPING_ADD_MORE_IDENTIFIERS` | Add more identifiers to offers that are demoted because of missing identifiers |
| `SHOPPING_ADD_SIZE` | Add the size to offers that are demoted because of a missing size |
| `SHOPPING_ADD_PRODUCTS_TO_CAMPAIGN` | Add products for a campaign to serve |
| `SHOPPING_FIX_DISAPPROVED_PRODUCTS` | Fix disapproved products |
| `SHOPPING_TARGET_ALL_OFFERS` | Create a catch-all campaign that targets all offers |
| `SHOPPING_FIX_SUSPENDED_MERCHANT_CENTER_ACCOUNT` | Fix Merchant Center account suspension issues |
| `SHOPPING_FIX_MERCHANT_CENTER_ACCOUNT_SUSPENSION_WARNING` | Fix Merchant Center account suspension warning issues |
| `DYNAMIC_IMAGE_EXTENSION_OPT_IN` | Enable dynamic image extensions on the account |
| `RAISE_TARGET_CPA` | Raise Target CPA |
| `LOWER_TARGET_ROAS` | Lower Target ROAS |
| `FORECASTING_SET_TARGET_CPA` | Set a target CPA for campaigns that don't have one specified, in advance of a seasonal event that is forecasted to increase traffic |
| `SET_TARGET_CPA` | Set a target CPA for campaigns that don't have one specified |
| `SET_TARGET_ROAS` | Set a target ROAS for campaigns that don't have one specified |
| `REFRESH_CUSTOMER_MATCH_LIST` | Update a customer list that hasn't been updated in the last 90 days |
| `IMPROVE_GOOGLE_TAG_COVERAGE` | Deploy the Google Tag on more pages |
| `CAMPAIGN_SPECIFIC_APP_GOAL` | Add a campaign-specific app conversion goal |
| `RAISE_TARGET_CPA_PERFORMANCE_BID_TOO_LOW` | Raise Target CPA when it is too low for Search campaigns |
| `LOWER_TARGET_ROAS_PERFORMANCE_BID_TOO_LOW` | Lower Target ROAS when it is too low for Search campaigns |
| `RAISE_BUDGET_PERFORMANCE_TOO_LOW` | Raise budget when it is too low for Search campaigns. Available starting in **v26** . Recommendation details are returned in [`Recommendation.raise_budget_performance_too_low_recommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.md.txt#raise_budget_performance_too_low_recommendation) and applied using [`ApplyRecommendationOperation.raise_budget_performance_too_low`](https://developers.google.com/google-ads/api/reference/rpc/v26/ApplyRecommendationOperation.md.txt#raise_budget_performance_too_low). |
| `OPTIMIZE_FOR_NEW_CUSTOMERS` | Set an incremental conversion value for new customers to optimize campaigns for [new customer acquisition](https://developers.google.com/google-ads/api/docs/conversions/goals/lifecycle-goals.md.txt#new-customer-acquisition-goal-settings). Available starting in **v26.1** . Recommendation details are returned in [`Recommendation.optimize_for_new_customers_recommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.md.txt#optimize_for_new_customers_recommendation) and applied using [`ApplyRecommendationOperation.optimize_for_new_customers`](https://developers.google.com/google-ads/api/reference/rpc/v26/ApplyRecommendationOperation.md.txt#optimize_for_new_customers). |
| `KEYWORD_MATCH_TYPE` (deprecated) | Deprecated, use `USE_BROAD_MATCH_KEYWORD` instead |

## Retrieve recommendations

Like most other entities in the Google Ads API, [`Recommendation`
objects](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation) are fetched by using the
[`GoogleAdsService.SearchStream`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsService/SearchStream.md.txt)
with a Google Ads Query Language query.

For each type of recommendation, details are provided in a
recommendation-specific field. For example, `CAMPAIGN_BUDGET` recommendation
details are in the
[`campaign_budget_recommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.md.txt#campaign_budget_recommendation) field, and are
wrapped in a [`CampaignBudgetRecommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.CampaignBudgetRecommendation.md.txt) object.

Find all recommendation-specific fields in the
[`recommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.md.txt#recommendation) union field.

### Recommendation impact

Some recommendation types populate the
[`impact`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.md.txt#impact) field of the recommendation.
[`RecommendationImpact`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.RecommendationImpact.md.txt)
contains an estimate of the impact on account performance as a result of
applying the recommendation. The following
[recommendation metrics](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.RecommendationMetrics.md.txt) are
available in the `impact.base_metrics` and `impact.potential_metrics` fields:

- `impressions`

- `clicks`

- `cost_micros`

- `conversions`

- `all_conversions`

- `video_views`

Even when the `impact` field is populated, metrics availability varies depending
on the recommendation type and campaign type, among other factors. In general,
check for availability of each impact metric before trying to use it.

### Code example

The following sample code retrieves all available and dismissed recommendations
of type `KEYWORD` from an account and prints some of their details:


### Java

```java
try (GoogleAdsServiceClient googleAdsServiceClient =
        googleAdsClient.getLatestVersion().createGoogleAdsServiceClient();
    RecommendationServiceClient recommendationServiceClient =
        googleAdsClient.getLatestVersion().createRecommendationServiceClient()) {
  // Creates a query that retrieves keyword recommendations.
  String query =
      "SELECT recommendation.resource_name, "
          + "  recommendation.campaign, "
          + "  recommendation.keyword_recommendation "
          + "FROM recommendation "
          + "WHERE recommendation.type = KEYWORD";
  // Constructs the SearchGoogleAdsStreamRequest.
  SearchGoogleAdsStreamRequest request =
      SearchGoogleAdsStreamRequest.newBuilder()
          .setCustomerId(Long.toString(customerId))
          .setQuery(query)
          .build();

  // Issues the search stream request to detect keyword recommendations that exist for the
  // customer account.
  ServerStream<SearchGoogleAdsStreamResponse> stream =
      googleAdsServiceClient.searchStreamCallable().call(request);

  // Creates apply operations for all the recommendations found.
  List<ApplyRecommendationOperation> applyRecommendationOperations = new ArrayList<>();
  for (SearchGoogleAdsStreamResponse response : stream) {
    for (GoogleAdsRow googleAdsRow : response.getResultsList()) {
      Recommendation recommendation = googleAdsRow.getRecommendation();
      System.out.printf(
          "Keyword recommendation '%s' was found for campaign '%s'%n",
          recommendation.getResourceName(), recommendation.getCampaign());
      KeywordInfo keyword = recommendation.getKeywordRecommendation().getKeyword();
      System.out.printf("\tKeyword = '%s'%n", keyword.getText());
      System.out.printf("\tMatch type = '%s'%n", keyword.getMatchType());

      // Creates an ApplyRecommendationOperation that will apply this recommendation, and adds
      // it to the list of operations.
      applyRecommendationOperations.add(buildRecommendationOperation(recommendation));
    }
  }
      
```

### C#

```c#
// Get the GoogleAdsServiceClient.
GoogleAdsServiceClient googleAdsService = client.GetService(
    Services.V26.GoogleAdsService);

// Creates a query that retrieves keyword recommendations.
string query = "SELECT recommendation.resource_name, " +
    "recommendation.campaign, recommendation.keyword_recommendation " +
    "FROM recommendation WHERE " +
    $"recommendation.type = KEYWORD";

List<ApplyRecommendationOperation> operations =
    new List<ApplyRecommendationOperation>();

try
{
    // Issue a search request.
    googleAdsService.SearchStream(customerId.ToString(), query,
        delegate (SearchGoogleAdsStreamResponse resp)
        {
            Console.WriteLine($"Found {resp.Results.Count} recommendations.");
            foreach (GoogleAdsRow googleAdsRow in resp.Results)
            {
                Recommendation recommendation = googleAdsRow.Recommendation;
                Console.WriteLine("Keyword recommendation " +
                    $"{recommendation.ResourceName} was found for campaign " +
                    $"{recommendation.Campaign}.");

                if (recommendation.KeywordRecommendation != null)
                {
                    KeywordInfo keyword =
                        recommendation.KeywordRecommendation.Keyword;
                    Console.WriteLine($"Keyword = {keyword.Text}, type = " +
                        "{keyword.MatchType}");
                }

                operations.Add(
                    BuildApplyRecommendationOperation(recommendation.ResourceName)
                );
            }
        }
    );
}
catch (GoogleAdsException e)
{
    Console.WriteLine("Failure:");
    Console.WriteLine($"Message: {e.Message}");
    Console.WriteLine($"Failure: {e.Failure}");
    Console.WriteLine($"Request ID: {e.RequestId}");
    throw;
}
      
```

### PHP

```php
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
// Creates a query that retrieves keyword recommendations.
$query = 'SELECT recommendation.resource_name, recommendation.campaign, '
    . 'recommendation.keyword_recommendation '
    . 'FROM recommendation '
    . 'WHERE recommendation.type = KEYWORD ';
// Issues a search request to detect keyword recommendations that exist for the
// customer account.
$response =
    $googleAdsServiceClient->search(SearchGoogleAdsRequest::build($customerId, $query));

$operations = [];
// Iterates over all rows in all pages and prints the requested field values for
// the recommendation in each row.
foreach ($response->iterateAllElements() as $googleAdsRow) {
    /** @var GoogleAdsRow $googleAdsRow */
    $recommendation = $googleAdsRow->getRecommendation();
    printf(
        "Keyword recommendation with resource name '%s' was found for campaign "
        . "with resource name '%s':%s",
        $recommendation->getResourceName(),
        $recommendation->getCampaign(),
        PHP_EOL
    );
    if (!is_null($recommendation->getKeywordRecommendation())) {
        $keyword = $recommendation->getKeywordRecommendation()->getKeyword();
        printf(
            "\tKeyword = '%s'%s\ttype = '%s'%s",
            $keyword->getText(),
            PHP_EOL,
            KeywordMatchType::name($keyword->getMatchType()),
            PHP_EOL
        );
    }
    // Creates an ApplyRecommendationOperation that will be used to apply this
    // recommendation, and adds it to the list of operations.
    $operations[] = self::buildRecommendationOperation($recommendation->getResourceName());
}
      
```

### Python

```python
googleads_service = client.get_service("GoogleAdsService")
query: str = """
    SELECT
      recommendation.campaign,
      recommendation.keyword_recommendation
    FROM recommendation
    WHERE
      recommendation.type = KEYWORD"""

# Detects keyword recommendations that exist for the customer account.
response: Iterable[GoogleAdsRow] = googleads_service.search(
    customer_id=customer_id, query=query
)

operations: List[ApplyRecommendationOperation] = []
for row in response:
    recommendation = row.recommendation
    print(
        f"Keyword recommendation ('{recommendation.resource_name}') "
        f"was found for campaign '{recommendation.campaign}."
    )

    keyword = recommendation.keyword_recommendation.keyword
    print(
        f"\tKeyword = '{keyword.text}'\n" f"\tType = '{keyword.match_type}'"
    )

    # Create an ApplyRecommendationOperation that will be used to apply
    # this recommendation, and add it to the list of operations.
    operations.append(
        build_recommendation_operation(client, recommendation.resource_name)
    )
      
```

### Ruby

```ruby
query = <<~QUERY
  SELECT recommendation.resource_name, recommendation.campaign,
      recommendation.keyword_recommendation
  FROM recommendation
  WHERE recommendation.type = KEYWORD
QUERY

google_ads_service = client.service.google_ads

response = google_ads_service.search(
  customer_id: customer_id,
  query: query,
)

operations = response.each do |row|
  recommendation = row.recommendation

  puts "Keyword recommendation ('#{recommendation.resource_name}') was found for "\
    "campaign '#{recommendation.campaign}'."

  if recommendation.keyword_recommendation
    keyword = recommendation.keyword_recommendation.keyword
    puts "\tKeyword = '#{keyword.text}'"
    puts "\ttype = '#{keyword.match_type}'"
  end

  build_recommendation_operation(client, recommendation.resource_name)
end
      
```

### Perl

```perl
# Create the search query.
my $search_query =
  "SELECT recommendation.resource_name, " .
  "recommendation.campaign, recommendation.keyword_recommendation " .
  "FROM recommendation " .
  "WHERE recommendation.type = KEYWORD";

# Get the GoogleAdsService.
my $google_ads_service = $api_client->GoogleAdsService();

my $search_stream_handler =
  Google::Ads::GoogleAds::Utils::SearchStreamHandler->new({
    service => $google_ads_service,
    request => {
      customerId => $customer_id,
      query      => $search_query
    }});

# Create apply operations for all the recommendations found.
my $apply_recommendation_operations = ();
$search_stream_handler->process_contents(
  sub {
    my $google_ads_row = shift;
    my $recommendation = $google_ads_row->{recommendation};
    printf "Keyword recommendation '%s' was found for campaign '%s'.\n",
      $recommendation->{resourceName}, $recommendation->{campaign};
    my $keyword = $recommendation->{keywordRecommendation}{keyword};
    printf "\tKeyword = '%s'\n",    $keyword->{text};
    printf "\tMatch type = '%s'\n", $keyword->{matchType};
    # Creates an ApplyRecommendationOperation that will apply this recommendation, and adds
    # it to the list of operations.
    push @$apply_recommendation_operations,
      build_recommendation_operation($recommendation);
  });
      
```

### curl

```console
# Gets keyword recommendations.
#
# Variables:
#   API_VERSION,
#   CUSTOMER_ID,
#   MANAGER_CUSTOMER_ID,
#   OAUTH2_ACCESS_TOKEN:
#     See https://developers.google.com/google-ads/api/rest/auth#request_headers
#     for details.
curl -f --request POST \
"https://googleads.googleapis.com/v${API_VERSION}/customers/${CUSTOMER_ID}/googleAds:search" \
--header "Content-Type: application/json" \
--header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \
--header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \
--data @- <<EOF
{
"query": "
  SELECT
    recommendation.campaign,
    recommendation.keyword_recommendation
  FROM recommendation
  WHERE
    recommendation.type = KEYWORD
"
}
EOF
      
```

<br />

## Take action

Any retrieved recommendation can be applied or dismissed.

Depending on the recommendation type, recommendations can change on a daily
basis or even multiple times a day. When that happens, a recommendation
object's [`resource_name`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.md.txt#resource_name) can
become obsolete after the recommendation is retrieved.

It is good practice to take action on recommendations shortly after retrieval.

### Apply recommendations

You can apply active or dismissed recommendations with the
[`ApplyRecommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationService/ApplyRecommendation.md.txt) method of the
[`RecommendationService`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationService.md.txt).

Recommendation types can have mandatory or optional parameters. Most
recommendations come with recommended values that are used by default.

Setting accounts for [auto-applying recommendations](https://developers.google.com/google-ads/api/docs/recommendations.md.txt#auto-apply) is not
supported for all recommendation types. However, you can implement similar
behavior for the recommendation types that are fully supported by the Google Ads API.
Refer to the [`DetectAndApplyRecommendations` code
example](https://developers.google.com/google-ads/api/samples/detect-and-apply-recommendations) to learn more.

Use the [`apply_parameters`](https://developers.google.com/google-ads/api/reference/rpc/v26/ApplyRecommendationOperation.md.txt#apply_parameters) union field of
`ApplyRecommendationOperation` to apply recommendations with specific parameter
values. Each suitable recommendation type has its own field. Any recommendation
type not listed in the `apply_parameters` field does not use these parameter
values.

> [!IMPORTANT]
> **Key Point:** When applying recommended keywords from the add new keywords recommendation, you are responsible for ensuring that your ads are compliant with advertising policies after keywords are inserted.

#### Code example

The following code demonstrates how to build the
[`ApplyRecommendationOperation`](https://developers.google.com/google-ads/api/reference/rpc/v26/ApplyRecommendationOperation.md.txt) and
how to override the recommended values if you want to replace them with your
own.


### Java

```java
/** Creates and returns an ApplyRecommendationOperation to apply the given recommendation. */
private ApplyRecommendationOperation buildRecommendationOperation(Recommendation recommendation) {
  // If you have a recommendation ID instead of a resource name, you can create a resource name
  // like this:
  // String resourceName = ResourceNames.recommendation(customerId, recommendationId);

  // Creates a builder to construct the operation.
  Builder operationBuilder = ApplyRecommendationOperation.newBuilder();

  // Each recommendation type has optional parameters to override the recommended values. Below is
  // an example showing how to override a recommended ad when a TextAdRecommendation is applied.
  // operationBuilder.getTextAdBuilder().getAdBuilder().setResourceName("INSERT_AD_RESOURCE_NAME");

  // Sets the operation's resource name to the resource name of the recommendation to apply.
  operationBuilder.setResourceName(recommendation.getResourceName());
  return operationBuilder.build();
}
      
```

### C#

```c#
private ApplyRecommendationOperation BuildApplyRecommendationOperation(
    string recommendationResourceName
)
{
    // If you have a recommendation_id instead of the resource_name you can create a
    // resource name from it like this:
    // string recommendationResourceName =
    //    ResourceNames.Recommendation(customerId, recommendationId)

    // Each recommendation type has optional parameters to override the recommended values.
    // This is an example to override a recommended ad when a TextAdRecommendation is
    // applied.
    // For details, please read
    // https://developers.google.com/google-ads/api/reference/rpc/latest/ApplyRecommendationOperation.
    /*
    Ad overridingAd = new Ad()
    {
        Id = "INSERT_AD_ID_AS_LONG_HERE"
    };
    applyRecommendationOperation.TextAd = new TextAdParameters()
    {
        Ad = overridingAd
    };
    */

    ApplyRecommendationOperation applyRecommendationOperation =
    new ApplyRecommendationOperation()
    {
        ResourceName = recommendationResourceName
    };

    return applyRecommendationOperation;
}
      
```

### PHP

```php
private static function buildRecommendationOperation(
    string $recommendationResourceName
): ApplyRecommendationOperation {
    // If you have a recommendation_id instead of the resource name, you can create a resource
    // name from it like this:
    /*
    $recommendationResourceName =
        ResourceNames::forRecommendation($customerId, $recommendationId);
    */

    // Each recommendation type has optional parameters to override the recommended values.
    // This is an example to override a recommended ad when a TextAdRecommendation is applied.
    // For details, please read
    // https://developers.google.com/google-ads/api/reference/rpc/latest/ApplyRecommendationOperation.
    /*
    $overridingAd = new Ad([
        'id' => 'INSERT_AD_ID_AS_INTEGER_HERE'
    ]);
    $applyRecommendationOperation->setTextAd(new TextAdParameters(['ad' => $overridingAd]));
    */

    // Issues a mutate request to apply the recommendation.
    $applyRecommendationOperation = new ApplyRecommendationOperation();
    $applyRecommendationOperation->setResourceName($recommendationResourceName);
    return $applyRecommendationOperation;
}
      
```

### Python

```python
def build_recommendation_operation(
    client: GoogleAdsClient, recommendation: str
) -> ApplyRecommendationOperation:
    """Creates a ApplyRecommendationOperation to apply the given recommendation.

    Args:
        client: an initialized GoogleAdsClient instance.
        recommendation: a resource name for the recommendation to be applied.
    """
    # If you have a recommendation ID instead of a resource name, you can create
    # a resource name like this:
    #
    # googleads_service = client.get_service("GoogleAdsService")
    # resource_name = googleads_service.recommendation_path(
    #   customer_id, recommendation.id
    # )

    operation: ApplyRecommendationOperation = client.get_type(
        "ApplyRecommendationOperation"
    )

    # Each recommendation type has optional parameters to override the
    # recommended values. Below is an example showing how to override a
    # recommended ad when a TextAdRecommendation is applied.
    #
    # operation.text_ad.ad.resource_name = "INSERT_AD_RESOURCE_NAME"
    #
    # For more details, see:
    # https://developers.google.com/google-ads/api/reference/rpc/latest/ApplyRecommendationOperation#apply_parameters

    operation.resource_name = recommendation
    return operation
      
```

### Ruby

```ruby
def build_recommendation_operation(client, recommendation)
  # If you have a recommendation_id instead of the resource_name
  # you can create a resource name from it like this:
  # recommendation_resource =
  #    client.path.recommendation(customer_id, recommendation_id)

  operations = client.operation.apply_recommendation
  operations.resource_name = recommendation_resource

  # Each recommendation type has optional parameters to override the recommended
  # values. This is an example to override a recommended ad when a
  # TextAdRecommendation is applied.
  #
  # text_ad_parameters = client.resource.text_ad_parameters do |tap|
  #   tap.ad = client.resource.ad do |ad|
  #     ad.id = "INSERT_AD_ID_AS_INTEGER_HERE"
  #   end
  # end
  # operation.text_ad = text_ad_parameters
  #
  # For more details, see:
  # https://developers.google.com/google-ads/api/reference/rpc/latest/ApplyRecommendationOperation#apply_parameters

  return operation
end
      
```

### Perl

```perl
sub build_recommendation_operation {
  my ($recommendation) = @_;

  # If you have a recommendation ID instead of a resource name, you can create a resource
  # name like this:
  # my $recommendation_resource_name =
  #   Google::Ads::GoogleAds::V26::Utils::ResourceNames::recommendation(
  #   $customer_id, $recommendation_id);

  # Each recommendation type has optional parameters to override the recommended values.
  # Below is an example showing how to override a recommended ad when a TextAdRecommendation
  # is applied.
  # my $overriding_ad = Google::Ads::GoogleAds::V26::Resources::Ad->new({
  #   id => "INSERT_AD_ID_AS_INTEGER_HERE"
  # });
  # my $text_ad_parameters =
  #   Google::Ads::GoogleAds::V26::Services::RecommendationService::TextAdParameters
  #   ->new({ad => $overriding_ad});
  # $apply_recommendation_operation->{textAd} = $text_ad_parameters;

  # Create an apply recommendation operation.
  my $apply_recommendation_operation =
    Google::Ads::GoogleAds::V26::Services::RecommendationService::ApplyRecommendationOperation
    ->new({
      resourceName => $recommendation->{resourceName}});

  return $apply_recommendation_operation;
}
      
```

### curl

> [!NOTE]
> **Note:** While a direct REST code sample for this step isn't provided here, you can achieve this using a manual REST request.   
>
> Refer to the Google Ads API REST interface documentation and the method-specific reference pages. You will need to construct the JSON payload based on the proto definitions.   
>
> Key Resources:
>
> - [Using REST](https://developers.google.com/google-ads/api/rest/overview.md.txt)
> - [REST Interface Structure](https://developers.google.com/google-ads/api/rest/design/overview.md.txt)
> - [JSON Field Mappings](https://developers.google.com/google-ads/api/rest/design/json-mappings.md.txt)
> - Consult the [REST API Reference](https://developers.google.com/google-ads/api/reference/rpc/latest/overview) for the specific service and method.

<br />

The next example calls [`ApplyRecommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationService/ApplyRecommendation.md.txt), sending the apply
recommendation operations that were created in the preceding code.


### Java

```java
// Issues a mutate request to apply the recommendations.
ApplyRecommendationResponse applyRecommendationsResponse =
    recommendationServiceClient.applyRecommendation(
        Long.toString(customerId), applyRecommendationOperations);
for (ApplyRecommendationResult applyRecommendationResult :
    applyRecommendationsResponse.getResultsList()) {
  System.out.printf(
      "Applied recommendation with resource name: '%s'.%n",
      applyRecommendationResult.getResourceName());
}
      
```

### C#

```c#
private void ApplyRecommendation(GoogleAdsClient client, long customerId,
    List<ApplyRecommendationOperation> operations)
{
    // Get the RecommendationServiceClient.
    RecommendationServiceClient recommendationService = client.GetService(
        Services.V26.RecommendationService);

    ApplyRecommendationRequest applyRecommendationRequest = new ApplyRecommendationRequest()
    {
        CustomerId = customerId.ToString(),
    };

    applyRecommendationRequest.Operations.AddRange(operations);

    ApplyRecommendationResponse response =
        recommendationService.ApplyRecommendation(applyRecommendationRequest);
    foreach (ApplyRecommendationResult result in response.Results)
    {
        Console.WriteLine("Applied a recommendation with resource name: " +
            result.ResourceName);
    }
}
      
```

### PHP

```php
private static function applyRecommendations(
    GoogleAdsClient $googleAdsClient,
    int $customerId,
    array $operations
): void {
    // Issues a mutate request to apply the recommendations.
    $recommendationServiceClient = $googleAdsClient->getRecommendationServiceClient();
    $response = $recommendationServiceClient->applyRecommendation(
        ApplyRecommendationRequest::build($customerId, $operations)
    );
    foreach ($response->getResults() as $appliedRecommendation) {
        /** @var Recommendation $appliedRecommendation */
        printf(
            "Applied a recommendation with resource name: '%s'.%s",
            $appliedRecommendation->getResourceName(),
            PHP_EOL
        );
    }
}
      
```

### Python

```python
def apply_recommendations(
    client: GoogleAdsClient,
    customer_id: str,
    operations: List[ApplyRecommendationOperation],
) -> None:
    """Applies a batch of recommendations.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID.
        operations: a list of ApplyRecommendationOperation messages.
    """
    # Issues a mutate request to apply the recommendations.
    recommendation_service = client.get_service("RecommendationService")
    response: ApplyRecommendationResult = (
        recommendation_service.apply_recommendation(
            customer_id=customer_id, operations=operations
        )
    )

    for result in response.results:
        print(
            "Applied a recommendation with resource name: "
            f"'{result.resource_name}'."
        )
      
```

### Ruby

```ruby
def apply_recommendations(client, customer_id, operations)
  # Issues a mutate request to apply the recommendation.
  recommendation_service = client.service.recommendation

  response = recommendation_service.apply_recommendation(
    customer_id: customer_id,
    operations: [operations],
  )

  response.results.each do |applied_recommendation|
    puts "Applied recommendation with resource name: '#{applied_recommendation.resource_name}'."
  end
end
      
```

### Perl

```perl
# Issue a mutate request to apply the recommendations.
my $apply_recommendation_response =
  $api_client->RecommendationService()->apply({
    customerId => $customer_id,
    operations => $apply_recommendation_operations
  });

foreach my $result (@{$apply_recommendation_response->{results}}) {
  printf "Applied recommendation with resource name: '%s'.\n",
    $result->{resourceName};
}
      
```

### curl

```console
# Applies a recommendation.
#
# Variables:
#   API_VERSION,
#   CUSTOMER_ID,
#   MANAGER_CUSTOMER_ID,
#   OAUTH2_ACCESS_TOKEN:
#     See https://developers.google.com/google-ads/api/rest/auth#request_headers
#     for details.
#
#   RECOMMENDATION_RESOURCE_NAME: The resource name of the recommendation to
#     apply, from the previous request.
curl -f --request POST \
"https://googleads.googleapis.com/v${API_VERSION}/customers/${CUSTOMER_ID}/recommendations:apply" \
--header "Content-Type: application/json" \
--header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \
--header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \
--data @- <<EOF
{
  "operations": [
    {
      "resourceName": "${RECOMMENDATION_RESOURCE_NAME}"
    }
  ]
}
EOF
      
```

<br />

### Dismiss recommendations

You can dismiss recommendations with the
[`RecommendationService`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationService.md.txt). The code
structure is similar to [applying recommendations](https://developers.google.com/google-ads/api/docs/recommendations.md.txt#apply), but instead you use
[`DismissRecommendationOperation`](https://developers.google.com/google-ads/api/reference/rpc/v26/DismissRecommendationRequest.DismissRecommendationOperation.md.txt) and
[`RecommendationService.DismissRecommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationService.md.txt#dismissrecommendation).

### Bulk operations and error handling

Both `ApplyRecommendation` and `DismissRecommendation` accept up to 100
operations per request. When sending multiple operations in a single request,
keep the following behaviors in mind:

- **Mixing recommendation types:** By default (`partial_failure = false`), all operations in a single request must target the same recommendation type; otherwise, the API returns [`RecommendationError.DIFFERENT_TYPES_NOT_SUPPORTED`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationErrorEnum.RecommendationError.md.txt#different_types_not_supported). To apply or dismiss recommendations of different types in the same request, set [`partial_failure`](https://developers.google.com/google-ads/api/docs/best-practices/partial-failures.md.txt) to `true` on the request so valid operations succeed independently.
- **Lifecycle errors:** Because recommendations are evaluated dynamically, a recommendation's state can change between retrieval and action. If a recommendation was already applied, already dismissed, or is no longer applicable, the API returns `RECOMMENDATION_ALREADY_APPLIED`, `RECOMMENDATION_ALREADY_DISMISSED`, or `RECOMMENDATION_INVALIDATED` in [`RecommendationError`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationErrorEnum.RecommendationError.md.txt).

## Automatically apply recommendations

You can use the [`RecommendationSubscriptionService`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationSubscriptionService.md.txt) to
automatically apply recommendations of a specific type.

To subscribe to a particular recommendation type, create a
[`RecommendationSubscription`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationSubscription.md.txt) object,
set the [`type`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationSubscription.md.txt#type) field to one of
the supported recommendation
[types](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationTypeEnum.RecommendationType.md.txt), and set the
[`status`](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationSubscription.md.txt#status) field to `ENABLED`.

#### Subscription-supported recommendation types

- `ENHANCED_CPC_OPT_IN`
- `KEYWORD`
- `KEYWORD_MATCH_TYPE`
- `LOWER_TARGET_ROAS`
- `MAXIMIZE_CLICKS_OPT_IN`
- `OPTIMIZE_AD_ROTATION`
- `RAISE_TARGET_CPA`
- `RESPONSIVE_SEARCH_AD`
- `RESPONSIVE_SEARCH_AD_IMPROVE_AD_STRENGTH`
- `SEARCH_PARTNERS_OPT_IN`
- `SET_TARGET_CPA`
- `SET_TARGET_ROAS`
- `TARGET_CPA_OPT_IN`
- `TARGET_ROAS_OPT_IN`
- `USE_BROAD_MATCH_KEYWORD`

### Retrieve subscriptions

To get information about an account's recommendation subscriptions, query the
[`recommendation_subscription`](https://developers.google.com/google-ads/api/fields/v26/recommendation_subscription.md.txt) resource.

To view changes that were automatically applied, query the
[`change_event`](https://developers.google.com/google-ads/api/fields/v26/change_event.md.txt) resource, filtering the
[`change_event.client_type`](https://developers.google.com/google-ads/api/fields/v26/change_event.md.txt#change_event.client_type) to
`GOOGLE_ADS_RECOMMENDATIONS_SUBSCRIPTION`.

## Recommendations in campaign construction

You can use
[`RecommendationService.GenerateRecommendationsRequest`](https://developers.google.com/google-ads/api/reference/rpc/v26/GenerateRecommendationsRequest.md.txt) to
generate recommendations during campaign construction, for a given set of
recommendation types.

`GenerateRecommendations` accepts as input a customer ID, an advertising channel
type which must be either [`SEARCH`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdvertisingChannelTypeEnum.AdvertisingChannelType.md.txt#search) or
[`PERFORMANCE_MAX`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdvertisingChannelTypeEnum.AdvertisingChannelType.md.txt#performance_max), a list of recommendation types to generate,
and various data points dependent on the specified types. It outputs a list of
`Recommendation` objects based on the data you provide. If there isn't
sufficient data to generate a recommendation for the requested
[`recommendation_types`](https://developers.google.com/google-ads/api/reference/rpc/v26/GenerateRecommendationsRequest.md.txt#recommendation_types%5B%5D), or if the campaign is already in the
recommended state, the result set won't contain a recommendation for that type.
Make sure your application handles the case where no recommendations are
returned for the requested recommendation types.

> [!IMPORTANT]
> **Important:** The `RecommendationService` doesn't provide errors when insufficient data is provided for a given recommendation type. Consult the documentation to determine which data to provide.

The following table describes the recommendation types that
`GenerateRecommendations` supports, and the fields you must provide to receive
recommendations for that type. As a best practice, send the
`GenerateRecommendations` request *after* all information has been collected
related to the requested recommendation types. For additional details on
required and optional fields, including nested fields, consult the
[reference documentation](https://developers.google.com/google-ads/api/reference/rpc/v26/GenerateRecommendationsRequest.md.txt).

| [RecommendationType](https://developers.google.com/google-ads/api/reference/rpc/v26/RecommendationTypeEnum.RecommendationType.md.txt) | Required fields | Optional fields |
|---|---|---|
| `CAMPAIGN_BUDGET` | For both Search and Performance Max campaigns, the following fields are required: - `asset_group_info` - `final_url` - `bidding_strategy_type` For Search campaigns only, the following fields are also required: <!-- --> - `country_code` - `language_code` - `positive_location_id` or `negative_location_id` - `ad_group_info.keywords` - `bidding_info. bidding_strategy_target_info. target_impression_share_info` if the bidding strategy is set to `TARGET_IMPRESSION_SHARE` | - `budget_info` - For Performance Max campaigns, provide a value in the `merchant_center_account_id` field to indicate to `RecommendationsService` to generate recommendations for retail, rather than standard, Performance Max campaigns. |
| `KEYWORD` | - `seed_info` | - `ad_group_info` |
| `MAXIMIZE_CLICKS_OPT_IN` | - `conversion_tracking_status` - `bidding_info` |   |
| `MAXIMIZE_CONVERSIONS_OPT_IN` | - `conversion_tracking_status` - `bidding_info` |   |
| `MAXIMIZE_CONVERSION_VALUE_OPT_IN` | - `conversion_tracking_status` - `bidding_info` |   |
| `SET_TARGET_CPA` | - `conversion_tracking_status` - `bidding_info` |   |
| `SET_TARGET_ROAS` | - `conversion_tracking_status` - `bidding_info` |   |
| `SITELINK_ASSET` Note: The returned [`SitelinkAssetRecommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.md.txt#sitelink_asset_recommendation) object will contain empty lists. If the `GenerateRecommendations` response contains a `SitelinkAssetRecommendation`, it can be treated as a signal to add at least one sitelink asset to the campaign. | - `campaign_sitelink_count` |   |
| `TARGET_CPA_OPT_IN` | - `conversion_tracking_status` - `bidding_info` |   |
| `TARGET_ROAS_OPT_IN` | - `conversion_tracking_status` - `bidding_info` |   |

### Example usage flow

Suppose your company is an advertising agency which provides a campaign
construction workflow to users, and you want to offer suggestions to users
during that flow. You can use [`GenerateRecommendationsRequest`](https://developers.google.com/google-ads/api/reference/rpc/v26/GenerateRecommendationsRequest.md.txt) to
generate recommendations on-demand, and incorporate those recommendations into
your campaign construction user interface.

The usage flow might look like the following:

1. A user comes to your application to create a Performance Max campaign.

2. The user provides some initial information as part of the campaign
   construction flow. For example, they provide details to build a single
   [`SitelinkAsset`](https://developers.google.com/google-ads/api/reference/rpc/v26/SitelinkAsset.md.txt), and they select
   [`TARGET_SPEND`](https://developers.google.com/google-ads/api/reference/rpc/v26/BiddingStrategyTypeEnum.BiddingStrategyType.md.txt#target_spend) as their
   [Smart Bidding](https://support.google.com/google-ads/answer/7066642) strategy.

3. You send a `GenerateRecommendationsRequest` which sets the following fields:

   - [`campaign_sitelink_count`](https://developers.google.com/google-ads/api/reference/rpc/v26/GenerateRecommendationsRequest.md.txt#campaign_sitelink_count): set to `1`, which is
     the number of sitelink assets on the work-in-progress campaign.

   - [`bidding_info`](https://developers.google.com/google-ads/api/reference/rpc/v26/GenerateRecommendationsRequest.md.txt#bidding_info): set the nested `bidding_strategy_type`
     field to `TARGET_SPEND`.

   - `conversion_tracking_status`: set to the
     [`ConversionTrackingStatus`](https://developers.google.com/google-ads/api/reference/rpc/v26/ConversionTrackingStatusEnum.ConversionTrackingStatus.md.txt) of this customer. For
     guidance on how to retrieve this field, visit the
     [Getting started](https://developers.google.com/google-ads/api/docs/conversions/getting-started.md.txt#conversion_tracking_setup) guide for conversion management.

   - `recommendation_types`: set to `[SITELINK_ASSET, MAXIMIZE_CLICKS_OPT_IN]`.

   - `advertising_channel_type`: set to `PERFORMANCE_MAX`.

   - `customer_id`: set to the ID of the customer creating the campaign.

4. You can take the recommendations in the
   [`GenerateRecommendationsResponse`](https://developers.google.com/google-ads/api/reference/rpc/v26/GenerateRecommendationsResponse.md.txt) --- in this case, a
   [`SitelinkAssetRecommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.md.txt#sitelink_asset_recommendation) and a
   [`MaximizeClicksOptInRecommendation`](https://developers.google.com/google-ads/api/reference/rpc/v26/Recommendation.MaximizeClicksOptInRecommendation.md.txt) --- and
   suggest them to the user by displaying them within your campaign
   construction interface. If the user accepts a suggestion, you can then
   incorporate it into the campaign creation request once the user completes
   the campaign construction flow.