Skip to content

google_ads_custom_audience

A custom audience is a segment you describe rather than one Google picks for you. You list the signals — search terms people used, sites they browsed, apps they use — and Google finds the people who match.

This is the targeting to reach for when you have no conversion data to learn from. Google’s automatic audiences work by watching what converts; if nothing on your site is tracked, there is nothing to learn from, and saying “people who searched for an ad blocker” out loud is the whole signal.

Example

resource "google_ads_custom_audience" "privacy_searchers" {
name = "Privacy tool searchers"
description = "People searching for ad and tracker blocking"
type = "SEARCH"
member { keyword = "ad blocker" }
member { keyword = "block trackers" }
member { keyword = "stop being tracked online" }
}

Then point a campaign at it:

resource "google_ads_campaign_criterion" "privacy_intent" {
campaign = google_ads_campaign.instream.id
audience {
custom_audience = google_ads_custom_audience.privacy_searchers.id
}
}

Schema

Required

  • name ( String )

Optional

  • description ( String )
  • type ( String ) One of: AUTO, INTEREST, PURCHASE_INTENT, SEARCH . Default "AUTO"; omit to manage at the default.
  • status ( String ) One of: ENABLED, REMOVED . Default "ENABLED"; omit to manage at the default.

Nested blocks documented below: member.

type says what kind of signal the segment is built from, and Google does not let you change it after the segment exists:

  • SEARCH — people who searched Google for your keyword members. The most direct form of intent.
  • INTEREST — people interested in the subjects your members describe. Broader reach, looser match.
  • PURCHASE_INTENT — people actively shopping for what your members describe.
  • AUTO — let Google decide from the members you gave it. This is the default when you leave type out.

Nested blocks

member

One signal. Repeat the block to list many — a segment is the union of its members. Set exactly one attribute per block:

  • keyword — a search term or phrase.
  • url — a site whose visitors are the signal (people who browse sites like this one, not visitors to your site — that’s a remarketing list, which bidsmith doesn’t build).
  • app — an app id whose users are the signal.
  • place_category — a place-category id for location interest.

Optional

  • keyword ( String )
  • url ( String )
  • place_category ( String )
  • app ( String )

Matching an audience that already exists

bidsmith matches a declared segment to a live one by name, the same way shared sets work. Declaring a segment whose name already exists in the account adopts it rather than creating a duplicate — which is how you bring a UI-built audience under management: run bidsmith refresh, keep the block it writes, and edit from there.

If you’d rather leave a segment unmanaged, don’t declare it — point the campaign’s audience block at its resource name instead:

audience {
custom_audience = "customers/1234567890/customAudiences/9876543210"
}

How it applies

Custom audiences are the one resource Google Ads won’t accept in the same request as everything else, so apply writes them in a call of their own that runs first — the campaigns and criteria that target them go in the main batch afterwards, pointing at the segments it just created.

Two things follow from that, both visible in plan:

  • A criterion targeting a segment that doesn’t exist yet shows as deferred rather than ok. There is nothing to validate it against until the segment is real; apply creates the segment and then applies the criterion normally.
  • The two calls aren’t one transaction. If the main batch fails after the segments were written, the segments stay. Re-running apply after fixing the error adopts them by name instead of creating duplicates.

See also