Skip to content

google_ads_campaign_criterion

A campaign criterion is targeting that applies to a whole campaign: negative keywords (excluded across every ad group), geo targets (which locations your ads can show in), language targets, proximity (latitude / longitude radius around a point), ad schedules (which days and hours the campaign runs), and device bid adjustments (spend more or less — or nothing at all — on a device type).

For video campaigns it is also how you say who should see the ad and where it can run: audiences, YouTube channels and videos, topics, interests, and age / gender.

Example

Block negative keywords campaign-wide:

resource "google_ads_campaign_criterion" "summer_negatives" {
campaign = google_ads_campaign.summer_search.id
status = "ENABLED"
negative_keyword {
text = "free"
match_type = "BROAD"
}
negative_keyword {
text = "diy"
match_type = "BROAD"
}
negative_keyword {
text = "used"
match_type = "BROAD"
}
}

Or, more compactly, with a negative_keywords list (optionally fanned out across match_types):

resource "google_ads_campaign_criterion" "summer_negatives" {
campaign = google_ads_campaign.summer_search.id
status = "ENABLED"
negative_keywords {
match_type = "BROAD"
texts = ["free", "diy", "used"]
}
}

Target the United States (geo target constant 2840):

resource "google_ads_campaign_criterion" "summer_geo_us" {
campaign = google_ads_campaign.summer_search.id
status = "ENABLED"
location {
geo_target_constant = "geoTargetConstants/2840"
}
}

Target Polish-speaking users (language constant 1030):

resource "google_ads_campaign_criterion" "summer_lang_pl" {
campaign = google_ads_campaign.summer_search.id
status = "ENABLED"
language {
language_constant = "languageConstants/1030"
}
}

Show only within 15 km of central Warsaw:

resource "google_ads_campaign_criterion" "summer_warsaw" {
campaign = google_ads_campaign.summer_search.id
status = "ENABLED"
proximity {
latitude = 52.229675
longitude = 21.012228
radius = 15
radius_units = "KILOMETERS"
}
}

Only spend during waking hours — one ad_schedule block per day, and one resource can hold the whole week, the same way one resource holds many negative_keyword blocks. Each block becomes its own criterion in the account. A campaign with no schedule runs around the clock; the moment you declare one window, the campaign serves only inside the windows you declare:

resource "google_ads_campaign_criterion" "daytime" {
campaign = google_ads_campaign.summer_search.id
ad_schedule {
day_of_week = "MONDAY"
start_hour = 8
start_minute = "ZERO"
end_hour = 22
end_minute = "ZERO"
}
ad_schedule {
day_of_week = "TUESDAY"
start_hour = 8
start_minute = "ZERO"
end_hour = 22
end_minute = "ZERO"
}
}

Stop showing on mobile entirely — a bid_modifier of 0 is a −100% adjustment, so nothing spends there. This is the classic setup for a browser-extension campaign, where installs only happen on desktop and mobile clicks are wasted budget:

resource "google_ads_campaign_criterion" "no_mobile" {
campaign = google_ads_campaign.extension_installs.id
bid_modifier = 0.0
device {
type = "MOBILE"
}
}

Or nudge bids rather than switch a device off — bid 20% more on desktop (bid_modifier = 1.2) and 30% less on tablets (bid_modifier = 0.7):

resource "google_ads_campaign_criterion" "desktop_boost" {
campaign = google_ads_campaign.summer_search.id
bid_modifier = 1.2
device {
type = "DESKTOP"
}
}
resource "google_ads_campaign_criterion" "tablet_trim" {
campaign = google_ads_campaign.summer_search.id
bid_modifier = 0.7
device {
type = "TABLET"
}
}

Narrowing a video campaign

Video campaigns are the case where targeting is the strategy. Show only to people who searched for what you sell, on the channels where they already watch, and exclude the slices you don’t want:

resource "google_ads_campaign_criterion" "privacy_intent" {
campaign = google_ads_campaign.instream.id
audience {
custom_audience = google_ads_custom_audience.privacy_searchers.id
}
}
resource "google_ads_campaign_criterion" "tech_channel" {
campaign = google_ads_campaign.instream.id
youtube_channel {
channel_id = "UCXuqSBlHAE6Xw-yeJA0Tunw"
}
}
resource "google_ads_campaign_criterion" "exclude_under_25" {
campaign = google_ads_campaign.instream.id
negative = true
age_range {
type = "AGE_RANGE_18_24"
}
}

Every one of these blocks takes negative = true to flip it from “target this” to “exclude this” — the same switch negative keywords use.

Schema

Required

  • campaign ( Reference to google_ads_campaign )

Optional

  • status ( String ) One of: ENABLED, PAUSED, REMOVED . Default "ENABLED"; omit to manage at the default.
  • negative ( Boolean ) Default false; omit to manage at the default.
  • bid_modifier ( Number )

Nested blocks documented below: keyword, negative_keyword, negative_keywords, device, location, language, proximity, ad_schedule, youtube_channel, youtube_video, topic, user_interest, age_range, gender, audience.

Nested blocks

keyword

A positive keyword scoped to the entire campaign. Uncommon — usually keywords live at ad-group scope. Use this only if you genuinely want a keyword to apply across every ad group.

Required

  • text ( String )
  • match_type ( String ) One of: EXACT, PHRASE, BROAD .

negative_keyword

A negative keyword that excludes searches campaign-wide. Repeat the block to list many. The most common use of google_ads_campaign_criterion.

Required

  • text ( String )
  • match_type ( String ) One of: EXACT, PHRASE, BROAD .

negative_keywords

The compact form: a list of texts fanned out across a single match_type or a list of match_types. One block stands in for many negative_keyword blocks. Set exactly one of match_type or match_types.

Required

  • texts ( List of String )

Optional

  • match_type ( String ) One of: EXACT, PHRASE, BROAD .
  • match_types ( List of String )

location

A geo target — restricts where your ads can show. Use Google’s geo target constants (e.g. geoTargetConstants/2840 for the United States).

Required

  • geo_target_constant ( String )

language

A language target — restricts what user-language settings can see your ads. Use Google’s language constants (e.g. languageConstants/1030 for Polish, languageConstants/1000 for English).

Required

  • language_constant ( String )

proximity

A circular radius target — ads only show to users within radius of the given (latitude, longitude). Use for hyperlocal campaigns.

Required

  • latitude ( Number )
  • longitude ( Number )
  • radius ( Number )
  • radius_units ( String ) One of: MILES, KILOMETERS .

ad_schedule

One day-and-hours window the campaign is allowed to serve in — the setting the Google Ads website calls an ad schedule (or dayparting). Repeat the block for each day: a Monday-to-Friday 8:00–22:00 schedule is five ad_schedule blocks — in one resource or spread across several — and lands as five criteria, one per day. Minutes snap to the quarter hour ("ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"), hours run 0–24, and a window can’t cross midnight — for an overnight window, declare one block up to 24 and another from 0.

Pair a window with the resource’s bid_modifier to bid more or less in that window instead of switching the rest of the week off entirely; the modifier applies to every window in the resource, so give a differently weighted window its own resource.

Works on Search and Demand Gen campaigns alike.

Required

  • day_of_week ( String ) One of: MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY .
  • start_hour ( Number )
  • start_minute ( String ) One of: ZERO, FIFTEEN, THIRTY, FORTY_FIVE .
  • end_hour ( Number )
  • end_minute ( String ) One of: ZERO, FIFTEEN, THIRTY, FORTY_FIVE .

device

A device bid adjustment. Pair a device block with the resource’s bid_modifier attribute to spend more, less, or nothing on a device type. type is one of MOBILE, DESKTOP, TABLET, CONNECTED_TV, or OTHER.

bid_modifier is a multiplier on your bid: 1.0 is no change, 1.25 bids 25% more, 0.5 bids 50% less, and 0.0 is a −100% adjustment that opts the device out completely. Editing the modifier later is an in-place update — Google Ads keeps the campaign’s history.

You only need to declare the device types you’re adjusting. As soon as a campaign has any device adjustment, Google Ads quietly adds entries for every other device type (desktop, mobile, tablet, and so on) at no adjustment — that’s normal, and bidsmith leaves them alone. If one of those undeclared types picks up an adjustment outside your files (say, someone changes it in the Google Ads website), plan prints a warning: add a matching device block to take it over, or leave out bid_modifier to clear the adjustment.

Required

  • type ( String ) One of: MOBILE, DESKTOP, TABLET, CONNECTED_TV, OTHER .

audience

Who should see the ad, by audience. Set exactly one of three sources:

  • custom_audience — a segment you build yourself from search terms, URLs, or apps. Point it at a google_ads_custom_audience you declare, or paste the resource name of one that already exists (customers/1234567890/customAudiences/9876).
  • user_list — a remarketing list (site visitors, customer match). bidsmith doesn’t build these; name the existing list by its resource name.
  • combined_audience — an audience assembled in the Google Ads website out of other audiences, again named by resource name.

Optional

  • custom_audience ( reference_or_resource_name )
  • user_list ( String )
  • combined_audience ( String )

youtube_channel

A YouTube channel to run on (or, with negative = true, to stay off). channel_id is the UC… id in the channel’s URL — youtube.com/channel/UCXuqSBlHAE6Xw-yeJA0Tunw. For a channel that only shows a handle (youtube.com/@somechannel), open any of its videos and click the channel name to get the UC… form.

Required

  • channel_id ( String )

youtube_video

A single YouTube video to run on. video_id is the 11-character id after watch?v=.

Required

  • video_id ( String )

topic

A subject category — ads run on videos and pages about that topic. Use Google’s verticals table for the id (e.g. topicConstants/278 for Computers & Electronics).

Required

  • topic_constant ( String )

user_interest

An affinity or in-market audience — people Google has classified by interest or purchase intent. Use Google’s user interest table for the id.

Required

  • user_interest_category ( String )

age_range

An age bracket. Most often used with negative = true to exclude one. Note AGE_RANGE_UNDETERMINED — people Google can’t place in a bracket, which is a large share of viewers; excluding it cuts reach hard.

Required

  • type ( String ) One of: AGE_RANGE_18_24, AGE_RANGE_25_34, AGE_RANGE_35_44, AGE_RANGE_45_54, AGE_RANGE_55_64, AGE_RANGE_65_UP, AGE_RANGE_UNDETERMINED .

gender

A gender bracket, with the same UNDETERMINED caveat as age_range.

Required

  • type ( String ) One of: MALE, FEMALE, UNDETERMINED .

See also