Vertical ads provide specialized features for AI Max for Search campaigns-enabled Search
campaigns that are linked to a vertical feed, such as hotels. You can control
which vertical ad formats are served at the ad group level, and you can control
which feed entities are targeted using vertical ads item group rules.

## Overview

This guide covers two main features for managing vertical ads:

1. **Format controls:** Opt in or opt out of specific ad formats (text ads, booking links, and vertical promotion ads) at the ad group level.
2. **Vertical ads items management:** Filter and target specific inventory from your linked vertical (formerly called travel) feed using a rule-based system that involves `SharedSet` and `SharedCriterion`.

## Prerequisites

Before you implement these features, make sure your campaign meets the following
requirements:

- **Campaign type:** Must be a Search campaign.
- **Vertical feed:** An active vertical data feed must be linked at the customer or campaign level. See [Link vertical data feeds at the campaign
  level](https://developers.google.com/google-ads/api/docs/campaigns/ai-max-for-search-campaigns/vertical-ads-controls#link-vertical-feeds) to link a feed at the campaign level. Linking a vertical data feed activates [Travel Feeds in Search Ads
  (TFSA)](https://developers.google.com/google-ads/api/docs/hotel-ads/travel-feeds) and enables vertical ads controls for the campaign.
- **AI Max for Search campaigns:** The AI Max for Search campaigns setting must be enabled on the campaign.

> [!NOTE]
> **Note:** Modifying format control settings on a campaign without AI Max for Search campaigns or an active vertical data feed fails with `VERTICAL_ADS_FORMAT_SETTING_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_AI_MAX` or `VERTICAL_ADS_FORMAT_SETTING_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_ENABLED_TRAVEL_FEED`. Similarly, adding an item group rule with a dimension that is not supported for the vertical type fails with `VERTICAL_ADS_ITEM_GROUP_RULE_NOT_SUPPORTED_FOR_THE_VERTICAL_TYPE`.

## Link vertical data feeds at the campaign level

To activate Travel Feeds in Search Ads (TFSA) and enable vertical ads controls
within your campaign, you can link your vertical data feed asset set at the
campaign level using the following steps. Alternatively, to enable these
features for all campaigns in your account, you can link the feed at the
customer level by following the [customer-level linking
instructions](https://developers.google.com/google-ads/api/docs/hotel-ads/travel-feeds#opt-out-at-the-customer-level) in the Travel Feeds in Search Ads guide.

1. Create a [`CampaignAssetSet`](https://developers.google.com/google-ads/api/reference/rpc/v26/CampaignAssetSet) object, setting `asset_set` to the resource name of your vertical feed asset set and `campaign` to the resource name of your campaign.
2. Create a [`CampaignAssetSetOperation`](https://developers.google.com/google-ads/api/reference/rpc/v26/CampaignAssetSetOperation) with `create` set to the `CampaignAssetSet`.
3. Submit the operation using [`CampaignAssetSetService.MutateCampaignAssetSets`](https://developers.google.com/google-ads/api/reference/rpc/v26/CampaignAssetSetService/MutateCampaignAssetSets).

For more details on managing travel feeds at scale, refer to the [Travel Feeds
in Search Ads](https://developers.google.com/google-ads/api/docs/hotel-ads/travel-feeds) documentation.

## Ad group format controls

You can configure which vertical ad formats are active for a specific ad
group. This is managed through the
[`vertical_ads_format_setting`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroup#vertical_ads_format_setting)
([`VerticalAdsFormatSetting`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroup.VerticalAdsFormatSetting)) field on the
[`AdGroup`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroup) resource.

### Available formats

- **Text ads ([`disable_text_ads`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroup.VerticalAdsFormatSetting#disable_text_ads)):** Enabled by default. Can be disabled.
- **Booking links ([`enable_booking_links`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroup.VerticalAdsFormatSetting#enable_booking_links)):** Opt-in required. Only supported for `HOTELS` and `THINGS_TO_DO` vertical feeds.
- **Vertical promotion ads
  ([`enable_vertical_promotion_ads`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroup.VerticalAdsFormatSetting#enable_vertical_promotion_ads)):** Opt-in required.

### Validation rules

- You cannot opt out of all three formats simultaneously for a single ad group.
- `enable_booking_links` can only be set to `true` when the campaign's active vertical feed is `HOTELS` or `THINGS_TO_DO`.
- These settings only apply to [`SEARCH_STANDARD`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupTypeEnum.AdGroupType#search_standard) and [`SEARCH_DYNAMIC_ADS`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupTypeEnum.AdGroupType#search_dynamic_ads) ad group types.

### Example: Update format settings

The following Java example demonstrates how to disable text ads and enable
vertical promotion ads for an existing ad group:

    // Assuming 'adGroup' is an existing AdGroup object.
    // Example resource name: "customers/{customer_id}/adGroups/{ad_group_id}"
    AdGroup adGroupToUpdate = AdGroup.newBuilder()
        .setResourceName(adGroup.getResourceName())
        .setVerticalAdsFormatSetting(
            AdGroup.VerticalAdsFormatSetting.newBuilder()
                .setDisableTextAds(true)
                .setEnableBookingLinks(false)
                .setEnableVerticalPromotionAds(true)
        )
        .build();

    AdGroupOperation operation = AdGroupOperation.newBuilder()
        .setUpdate(adGroupToUpdate)
        .setUpdateMask(FieldMasks.allSetFieldsOf(adGroupToUpdate))
        .build();

    // Submit the operation using AdGroupService...

## Vertical ads items management

To target a specific subset of your feed inventory, such as "Hotels in Boston"
or "Exclude 1-star hotels", you must use vertical ads item group rules.

### How the data model works

The data model uses a shared criteria approach:

1. [`SharedSet`](https://developers.google.com/google-ads/api/reference/rpc/v26/SharedSet): Create a [`SharedSet`](https://developers.google.com/google-ads/api/reference/rpc/v26/SharedSet) with type [`VERTICAL_ADS_ITEM_GROUP_RULE_LIST`](https://developers.google.com/google-ads/api/reference/rpc/v26/SharedSetTypeEnum.SharedSetType#vertical_ads_item_group_rule_list).
2. [`SharedCriterion`](https://developers.google.com/google-ads/api/reference/rpc/v26/SharedCriterion): Add rules (criteria) to this set. Each rule specifies a dimension, such as City or Hotel Class, and a value. You can also create negative criteria to exclude items.
3. [`AdGroupCriterion`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupCriterion): Link the [`SharedSet`](https://developers.google.com/google-ads/api/reference/rpc/v26/SharedSet) to your [`AdGroup`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroup) using an [`AdGroupCriterion`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupCriterion) ([`vertical_ads_item_group_rule_list`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupCriterion#vertical_ads_item_group_rule_list)).

### Supported dimensions

You can filter entities based on the following dimensions in
[`SharedCriterion`](https://developers.google.com/google-ads/api/reference/rpc/v26/SharedCriterion)
([`VerticalAdsItemGroupRuleInfo`](https://developers.google.com/google-ads/api/reference/rpc/v26/VerticalAdsItemGroupRuleInfo)), depending on the
`SharedSet`'s `vertical_ads_item_vertical_type`:

- `item_code`: Specific listing ID (supported for all vertical types).
- `city_criterion_id`, `region_criterion_id`, `country_criterion_id`: Geo Target Constant resource names (`geoTargetConstants/{id}`; supported for all vertical types except `FLIGHTS`).
- `hotel_class`: Star rating from 1 to 5 (`HOTELS` only).
- `user_rating` (starting in **`v24`** ): Rounded floor user rating from 1 to 5 (`THINGS_TO_DO` only).
- `venue`, `event_participant_display_name` (starting in **`v24`** ): Event venue and participant display name filters (`EVENTS` only).

### Code example: Create and link rules

This Python example creates a rule to include items in "Boston" or
"San Francisco" and exclude "1-star" and "2-star" hotels:

    # 1. Create the SharedSet
    shared_set_operation = client.get_type("SharedSetOperation")
    shared_set = shared_set_operation.create
    shared_set.name = "Boston/SF Premium Hotels"
    shared_set.type_ = (
        client.enums.SharedSetTypeEnum.VERTICAL_ADS_ITEM_GROUP_RULE_LIST
    )
    shared_set.vertical_ads_item_vertical_type = (
        client.enums.VerticalAdsItemVerticalTypeEnum.HOTELS
    )
    shared_set_service = client.get_service("SharedSetService")
    shared_set_response = shared_set_service.mutate_shared_sets(
        customer_id=customer_id, operations=[shared_set_operation]
    )
    shared_set_resource_name = shared_set_response.results[0].resource_name

    # 2. Add Criteria (Rules) to the SharedSet
    shared_criteria_operations = []

    # Rule A: Include Boston and SF
    geo_target_constant_service = client.get_service("GeoTargetConstantService")
    included_city_ids = [1006543, 1014221]  # Geo Target Constant IDs
    for city_id in included_city_ids:
      op = client.get_type("SharedCriterionOperation")
      criterion = op.create
      criterion.shared_set = shared_set_resource_name
      criterion.vertical_ads_item_group_rule.city_criterion_id = (
          geo_target_constant_service.geo_target_constant_path(city_id)
      )
      shared_criteria_operations.append(op)

    # Rule B: Exclude 1 and 2 Star Hotels
    excluded_stars = [1, 2]
    for star_rating in excluded_stars:
      op = client.get_type("SharedCriterionOperation")
      criterion = op.create
      criterion.shared_set = shared_set_resource_name
      criterion.vertical_ads_item_group_rule.hotel_class = star_rating
      criterion.negative = True  # Mark as exclusion
      shared_criteria_operations.append(op)

    # Submit SharedCriterionOperations...

    # 3. Link to AdGroup
    ad_group_service = client.get_service("AdGroupService")
    ad_group_resource_name = ad_group_service.ad_group_path(
        customer_id, ad_group_id
    )
    agc_operation = client.get_type("AdGroupCriterionOperation")
    agc = agc_operation.create
    agc.ad_group = ad_group_resource_name
    agc.status = client.enums.AdGroupCriterionStatusEnum.ENABLED
    agc.vertical_ads_item_group_rule_list.shared_set = shared_set_resource_name

    # Submit AdGroupCriterionOperation...

### Per-entity manual CPC bidding

Starting in **`v25`** , for Search Campaigns for Travel (Search campaigns with
AI Max for Search campaigns enabled and a linked hotel feed) that use the Manual CPC
([`BiddingStrategyType.MANUAL_CPC`](https://developers.google.com/google-ads/api/reference/rpc/v26/BiddingStrategyTypeEnum.BiddingStrategyType#manual_cpc)) bidding strategy, you can
set manual CPC bid overrides (`cpc_bid_micros`) for individual hotel feed items
using the [`EntityBid`](https://developers.google.com/google-ads/api/reference/rpc/v26/EntityBid)
([`ad_group_criterion.entity_bid`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupCriterion#entity_bid)) criterion with
[`CriterionType.VERTICAL_ADS_ITEM_BID`](https://developers.google.com/google-ads/api/reference/rpc/v26/CriterionTypeEnum.CriterionType#vertical_ads_item_bid) and
[`entity_bid.item_code`](https://developers.google.com/google-ads/api/reference/rpc/v26/EntityBid#item_code).

Negative criteria (`negative = true`), non-Search campaigns, and automated or
Smart Bidding strategies are not supported for `VERTICAL_ADS_ITEM_BID` and
return
[`ContextError.OPERATION_NOT_PERMITTED_FOR_CONTEXT`](https://developers.google.com/google-ads/api/reference/rpc/v26/ContextErrorEnum.ContextError#operation_not_permitted_for_context).
Performance metrics are not populated on `VERTICAL_ADS_ITEM_BID` criteria. For
full schema details, GAQL queries, and mutate payload examples, see [Per-entity
manual CPC bidding](https://developers.google.com/google-ads/api/docs/hotel-ads/travel-feeds#entity-bidding) in the Travel Feeds in Search
Ads guide. To set multiplicative ad group bid adjustments across travel
itinerary dimensions for hotel ads using
[`AdGroupBidModifier`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupBidModifier), see
[Adjust bids with bid modifiers](https://developers.google.com/google-ads/api/docs/hotel-ads/bidding/create-ad-group-bid-modifier).

## Performance reports

You can retrieve performance metrics for vertical ads using the
`GoogleAdsService.SearchStream` or `GoogleAdsService.Search` methods.

### Vertical ads segments

- [`segments.vertical_ads_hotel_class`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_hotel_class): Integer value (1 to 5 stars) specifying the class rating for a hotel listing.
- [`segments.vertical_ads_listing`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_listing): Identifier for a specific vertical ad listing.
- [`segments.vertical_ads_listing_brand`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_listing_brand): Brand associated with a vertical ad listing.
- [`segments.vertical_ads_listing_city`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_listing_city): The city associated with the listing.
- [`segments.vertical_ads_listing_country`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_listing_country): The country associated with the listing.
- [`segments.vertical_ads_listing_region`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_listing_region): The region associated with the listing.
- [`segments.vertical_ads_partner_account`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_partner_account): The partner account within a Partner Center (for example, Hotel Center) that supplies inventory feed data.
- [`segments.vertical_ads_vertical`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_vertical): The vertical type, such as hotel or rental car.
- [`segments.vertical_ads_event_participant_display_names`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_event_participant_display_names): The display names of participants in an event listing, such as performers, speakers, or teams.
- [`segments.vertical_ads_listing_user_rating`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_listing_user_rating) (starting in **`v24`**): Integer value (1 to 5) specifying the user rating of the vertical ads listing.
- [`segments.vertical_ads_listing_venue`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_listing_venue) (starting in **`v24`**): The name of the venue for the vertical ads listing (for example, a concert venue).
- [`segments.vertical_ads_price_tier`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_price_tier) (starting in **`v25`**): Relative price competitiveness bucket for hotel listings.
- [`segments.vertical_ads_rate_rule_id`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_rate_rule_id) (starting in **`v25`**): String identifier corresponding to private or conditional rate rules applied to the bid or impression.
- [`segments.vertical_ads_rate_type`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#vertical_ads_rate_type) (starting in **`v25`**): Categorization of the public, private, or conditional rate type.

### Itinerary dimension segments

Starting in **`v25`**, for vertical ads linked to travel and accommodation
feeds, you can segment performance reports using itinerary dimensions:

- [`segments.advance_booking_window`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#advance_booking_window): The advance booking window for the itinerary in days.
- [`segments.length_of_booking`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#length_of_booking): The length of booking for the itinerary in days.
- [`segments.start_date`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#start_date): The start date of the booking formatted as `yyyy-MM-dd`.
- [`segments.start_day_of_week`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#start_day_of_week): The start day of week of the booking.
- [`segments.user_set_dates`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments#user_set_dates): Indicates whether user-specified dates were selected ([`USER_SELECTED`](https://developers.google.com/google-ads/api/reference/rpc/v26/DateSelectionTypeEnum.DateSelectionType#user_selected) or [`DEFAULT_SELECTION`](https://developers.google.com/google-ads/api/reference/rpc/v26/DateSelectionTypeEnum.DateSelectionType#default_selection)).

### Vertical ads metrics

Starting in **`v25`**, you can retrieve the following vertical ads metrics:

- [`metrics.vertical_ads_potential_impressions`](https://developers.google.com/google-ads/api/reference/rpc/v26/Metrics#vertical_ads_potential_impressions): Potential impressions representing the total view-capped eligible impressions available across the query context.
- [`metrics.vertical_ads_average_booking_value_micros`](https://developers.google.com/google-ads/api/reference/rpc/v26/Metrics#vertical_ads_average_booking_value_micros): Click-weighted average daily rate in micros, including taxes and fees, over the total length of stay.
- [`metrics.vertical_ads_price_difference_percentage`](https://developers.google.com/google-ads/api/reference/rpc/v26/Metrics#vertical_ads_price_difference_percentage): Percentage delta comparing the advertiser's offered price against the lowest competing price for the same property.

Starting in **`v26`** , you can also query the
[`metrics.search_top_impression_share`](https://developers.google.com/google-ads/api/reference/rpc/v26/Metrics#search_top_impression_share) and
[`metrics.search_click_share`](https://developers.google.com/google-ads/api/reference/rpc/v26/Metrics#search_click_share) metrics alongside both the
`segments.vertical_ads_*` segments and the [itinerary dimension
segments](https://developers.google.com/google-ads/api/docs/campaigns/ai-max-for-search-campaigns/vertical-ads-controls#itinerary-segments).

> [!NOTE]
> **Note:** In a single GAQL query:

- You can't select the `metrics.vertical_ads_*` metrics together with the itinerary dimension segments (`segments.advance_booking_window`, `segments.length_of_booking`, `segments.start_date`, `segments.start_day_of_week`, and `segments.user_set_dates`).
- The itinerary dimension segments are compatible only with the listing-level and partner-level vertical ads segments (`segments.vertical_ads_hotel_class`, `segments.vertical_ads_listing`, `segments.vertical_ads_listing_brand`, `segments.vertical_ads_listing_city`, `segments.vertical_ads_listing_country`, `segments.vertical_ads_listing_region`, `segments.vertical_ads_partner_account`, and `segments.vertical_ads_vertical`).
- You can't combine the rate-specific and event-specific vertical ads segments (`segments.vertical_ads_price_tier`, `segments.vertical_ads_rate_rule_id`, `segments.vertical_ads_rate_type`, `segments.vertical_ads_event_participant_display_names`, `segments.vertical_ads_listing_user_rating`, and `segments.vertical_ads_listing_venue`) with the itinerary dimension segments.

### Sample GAQL queries

This query retrieves vertical ads competitive and booking metrics segmented by
listing city, price tier, and rate type:

    SELECT
      campaign.id,
      ad_group.id,
      segments.vertical_ads_listing_city,
      segments.vertical_ads_price_tier,
      segments.vertical_ads_rate_type,
      metrics.vertical_ads_potential_impressions,
      metrics.vertical_ads_average_booking_value_micros,
      metrics.vertical_ads_price_difference_percentage,
      metrics.search_top_impression_share,
      metrics.search_click_share
    FROM
      ad_group
    WHERE
      segments.date DURING LAST_30_DAYS

This query segments standard performance metrics and impression or click share
metrics by vertical ads listing city and itinerary booking dimensions:

    SELECT
      campaign.id,
      ad_group.id,
      segments.vertical_ads_listing_city,
      segments.advance_booking_window,
      segments.length_of_booking,
      segments.start_date,
      metrics.impressions,
      metrics.clicks,
      metrics.all_conversions_value,
      metrics.search_top_impression_share,
      metrics.search_click_share
    FROM
      ad_group
    WHERE
      segments.date DURING LAST_30_DAYS

## Error handling

These are common errors you may encounter when configuring vertical ads:

| Error code | Cause | Recommended action |
|---|---|---|
| [`AdGroupError.INVALID_VERTICAL_ADS_FORMAT_SETTING`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupErrorEnum.AdGroupError#invalid_vertical_ads_format_setting) | All three ad formats (text, booking link, promotion ads) were disabled simultaneously, or `enable_booking_links` was enabled for a vertical other than `HOTELS` or `THINGS_TO_DO`. | Ensure at least one format is enabled in `VerticalAdsFormatSetting`, and only enable booking links for `HOTELS` or `THINGS_TO_DO` feeds. |
| [`AdGroupError.VERTICAL_ADS_FORMAT_SETTING_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_AI_MAX`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupErrorEnum.AdGroupError#vertical_ads_format_setting_not_supported_for_campaigns_without_ai_max) | The campaign does not have AI Max for Search campaigns enabled. | Enable AI Max for Search campaigns in campaign settings. |
| [`AdGroupError.VERTICAL_ADS_FORMAT_SETTING_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_ENABLED_TRAVEL_FEED`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupErrorEnum.AdGroupError#vertical_ads_format_setting_not_supported_for_campaigns_without_enabled_travel_feed) | The campaign lacks an active vertical data feed. | Ensure a valid vertical feed is linked at the customer or campaign level. |
| [`CriterionError.VERTICAL_ADS_ITEM_GROUP_RULE_LIST_DOES_NOT_EXIST`](https://developers.google.com/google-ads/api/reference/rpc/v26/CriterionErrorEnum.CriterionError#vertical_ads_item_group_rule_list_does_not_exist) | The `SharedSet` resource name provided in the `AdGroupCriterion` does not exist or does not have type `VERTICAL_ADS_ITEM_GROUP_RULE_LIST`. | Verify the `shared_set` resource name references an existing `SharedSet` of type `VERTICAL_ADS_ITEM_GROUP_RULE_LIST`. |
| [`CriterionError.CANNOT_ADD_REMOVED_VERTICAL_ADS_ITEM_GROUP_RULE_LIST_SHARED_SET`](https://developers.google.com/google-ads/api/reference/rpc/v26/CriterionErrorEnum.CriterionError#cannot_add_removed_vertical_ads_item_group_rule_list_shared_set) | The `SharedSet` referenced in the `AdGroupCriterion` has status `REMOVED`. | Reference an enabled `SharedSet` of type `VERTICAL_ADS_ITEM_GROUP_RULE_LIST`. |
| [`CriterionError.VERTICAL_ADS_ITEM_GROUP_RULE_NOT_SUPPORTED_FOR_THE_VERTICAL_TYPE`](https://developers.google.com/google-ads/api/reference/rpc/v26/CriterionErrorEnum.CriterionError#vertical_ads_item_group_rule_not_supported_for_the_vertical_type) | The criterion dimension used is not supported for the specific vertical, such as hotel class for car rentals. | Check that the `vertical_ads_item_group_rule` dimension matches your vertical type. |