Skip to content

Put a video ad's tracking URL under review

A YouTube video test is measured on the UTM parameters hanging off its landing page URL — something like ?utm_campaign=GH_YouTubeUS_v1_0811-instream. Get that slug wrong and the campaign still runs, still spends, and reports its results into the wrong bucket, or into no bucket at all.

If the ad was built in the Google Ads UI and left there, that slug is a text field in a web form. Nobody reviews it, nothing diffs it, and the only way to check it is to click into the ad. This recipe brings the ad itself into your .bid files so the URL is a line someone approves.

Pull the ad you already have

You don’t write the block by hand. refresh reads the account and renders the live creative into a .bid file:

Terminal window
bidsmith refresh -o campaigns/youtube-us.bid

The video ad comes out looking like this:

resource "google_ads_youtube_video_asset" "ghostery_12s" {
youtube_video_id = "dQw4w9WgXcQ"
}
resource "google_ads_ad_group_ad" "us_instream" {
ad_group = google_ads_ad_group.us_instream.id
status = "ENABLED"
ad {
final_urls = ["https://www.ghostery.com/?utm_campaign=GH_YouTubeUS_v1_0811-instream"]
final_mobile_urls = ["https://m.ghostery.com/?utm_campaign=GH_YouTubeUS_v1_0811-instream"]
display_url = "www.ghostery.com"
video_ad {
video = google_ads_youtube_video_asset.ghostery_12s.id
}
}
}

video_ad is the creative a UI-built video campaign carries. refresh renders it along with the two other URL fields — final_mobile_urls, which overrides the landing page on phones, and display_url, the shortened address the ad shows rather than navigates to.

Commit it, then plan

  1. Commit the file. The tracking URL is now in version control, and the next person to change it has to open a pull request to do it.

  2. Run bidsmith plan. The ad reports as an adoption — bidsmith found the live ad and will label it, changing nothing else:

    google_ads_ad_group_ad.us_instream ~ adopt (label only)
  3. Apply. From here on the file and the ad are joined, and a plan that says unchanged is speaking about that URL.

Mark it adopt-only

The ad exists; bidsmith should find it, not make a second one. Say so:

resource "google_ads_ad_group_ad" "us_instream" {
ad_group = google_ads_ad_group.us_instream.id
lifecycle {
create = false
}
ad { /* … */ }
}

Now a block that matches nothing live stops the plan with an explanation, rather than quietly turning into a create.

What you get

  • The UTM slug every video test is measured on is reviewable, and a change to it shows up as a diff with a name attached.
  • unchanged on that ad now means something. An ad body is compared whole, so if someone edits the URL in the Google Ads UI the file stops matching the live ad and the next plan says so — where before the field was invisible to bidsmith and every plan reported agreement.
  • bidsmith drift stops listing these fields as gaps, because they are now compared rather than merely present.

See also