Skip to content

Stop Google writing your ad copy

Your ads are running headlines nobody wrote. They read like your landing page, roughly, with the odd sentence that runs on past where a person would have stopped — and they change without a PR.

That’s asset automation: Google Ads generating headlines and descriptions for your campaign out of your landing pages, your existing ads, and generative AI. It’s a campaign setting, so you can declare it off in your .bid and keep it off.

Say no in the file

resource "google_ads_campaign" "brand_search" {
name = "Brand — Search"
advertising_channel_type = "SEARCH"
campaign_budget = google_ads_campaign_budget.brand.id
asset_automation_settings {
text_asset_automation = "OPTED_OUT"
final_url_expansion_text_asset_automation = "OPTED_OUT"
}
}
bidsmith plan .
google_ads_campaign.brand_search ~ update
asset_automation_settings: text_asset_automation=OPTED_IN -> text_asset_automation=OPTED_OUT, fi…
Plan: 0 to create, 1 to update, 0 to destroy, 12 unchanged.

bidsmith apply . sends it. From then on the campaign’s ads say what your files say.

The two settings do different things:

  • text_asset_automation — the one most people mean. Google writes extra headlines and descriptions across the campaign’s ads.
  • final_url_expansion_text_asset_automation — Google sends clicks to landing pages it picks from your site, and writes copy to match whichever page it picked. Turning this off is also what makes turning the first one off complete: while URL expansion runs, generated text comes with it.

Keeping it off

The value of declaring it is what happens next time. Someone opens the Google Ads UI, switches text customization back on, and the next plan says so:

google_ads_campaign.brand_search ~ update
asset_automation_settings: text_asset_automation=OPTED_IN, fi… -> text_asset_automation=OPTED_O…

Run bidsmith plan --detailed-exitcode . in CI and that drift fails the build. Nothing has to be noticed by a person.

Two limits worth knowing:

  • These settings exist on Search and Performance Max campaigns only. bidsmith validate warns if you put the block on anything else.
  • Defaults differ: a Search campaign starts opted out of text automation and URL expansion, a Performance Max campaign starts opted in to everything, including image and video generation.

The sibling switch: AI Max

Opting out of asset automation says “do not write my ad copy.” AI Max is the setting that lets Google decide which searches your ads answer — and write copy for the ones your keywords never named. Same fence, different post, and a campaign that never mentions it follows whatever Google’s default is on the day:

resource "google_ads_campaign" "brand_search" {
name = "Brand — Search"
advertising_channel_type = "SEARCH"
campaign_budget = google_ads_campaign_budget.brand.id
asset_automation_settings {
text_asset_automation = "OPTED_OUT"
final_url_expansion_text_asset_automation = "OPTED_OUT"
}
ai_max_setting {
enable_ai_max = false
}
}
resource "google_ads_ad_group" "brand" {
name = "Brand terms"
campaign = google_ads_campaign.brand_search.id
type = "SEARCH_STANDARD"
ai_max_ad_group_setting {
disable_search_term_matching = true
}
}

The campaign-level switch is the one that matters; the ad-group one is there for the case where AI Max is on across the campaign and one ad group should keep matching only what it declares.

google_ads_campaign.brand_search ~ update
ai_max_setting.enable_ai_max: (unset) -> false

An (unset) on the left is the point of writing the line: the account was not saying no, it was saying nothing. AI Max is a Search-campaign feature — validate warns if the block turns up anywhere else.

The third one: dynamic search ads

Asset automation writes copy for the ads you declared. AI Max decides which searches they answer. Dynamic search ads skip the ads entirely: Google crawls your site and generates a headline and a landing page per search.

It is not an on/off flag but a targeting mode, so it is declared as the scope it is:

resource "google_ads_campaign" "site_wide" {
name = "Site — dynamic"
advertising_channel_type = "SEARCH"
campaign_budget = google_ads_campaign_budget.site.id
dynamic_search_ads_setting {
domain_name = "example.com"
language_code = "en"
use_supplied_urls_only = true
}
}

use_supplied_urls_only = true is the important line: Google may still generate headlines, but only against landing pages you supplied, instead of anything it finds on the domain.

The case worth checking for is a campaign that has this and never mentions it — often a paused one nobody has looked at in a while, where nothing is serving today and enabling it would start generated ads with no diff anywhere. plan will not switch it off (a setting no file declares is not bidsmith’s to clear), but it does say so every run:

plan: warning: google_ads_campaign.site_wide has dynamic search ads
configured live (example.com (en)) and declares no
`dynamic_search_ads_setting` block: Google writes headlines and picks
landing pages from that site, and nothing in the file says so.

Run bidsmith refresh --in-place . to write the live values into the file, and it is under review like everything else.

The switch that isn’t in the file

Dynamic sitelinks, dynamic callouts, and the business name and logo that Google attaches by itself are a different feature: an account-level “automatically created assets” setting that the Google Ads API does not expose at all. No .bid can turn it off.

What bidsmith can do is stop the results serving, and tell you the switch is on:

plan: warning: account: Google's asset automation is serving 6 asset(s)
nothing declares (4 SITELINK, 2 CALLOUT). Add
`owns = ["automatically_created_assets"]` to the campaign — or to the
`provider` block for the account-level ones — and bidsmith will pause them
so they stop serving.

That line comes back on every plan while the switch is on, so flipping it in the UI is caught on the next run.

  1. Claim what it already attached. Add owns = ["automatically_created_assets"] to the campaign, or to the provider block for account-level assets. The next plan shows a ~ pause row per asset, and apply stops them serving. They are paused rather than deleted because Google reattaches anything bidsmith removes — see Serve only the extensions you declared.

  2. Turn the switch off in the Google Ads UI so no new ones are made. Admin → Account settings → Automatically created assets.

  3. Run bidsmith plan . and check the warning is gone.

See also