Skip to content
Excluding Placements using a script

Placement Exclusion Script – Google Display Ads

We use numerous scripts to improve advertiser performance across Google’s Display Network (GDN). One of the quickest steps to making Google Display Network (GDN) more effective is through the use of a Placement Exclusion Script. In this post we describe a basic version of this Google Ads script to automatically block underperforming placements across display ads.

What does the script do?

The script will collect performance metrics by placement URL and, based upon defined thresholds, add the URL to a defined Placement Exclusion List. Thresholds can be changed to suit advertiser requirements, with an exclusion based on a set amount of minimum impressions, conversion rate, and clicks.

What are the benefits?

Poorly performing placements (in this case websites) will be automatically excluded at desired intervals. As a result, this will reduce wasted budget, lead to an improved conversion rate and therefore ROAS (Return on Ad Spend) allowing accounts to scale! Even better, the exclusion list can be used across other campaigns or accounts assisting those too.

All that said, we strongly recommend previewing the results of this script before pushing to a live advertiser account. This can be done in the script tool within Google Ads.

Setup

  1. Create a Placement Exclusion List and apply it to the display campaigns you want to improve.
    In our example we created one called Auto Placement (Scripts) – Performance. If you create one with a different name you must update the script to reflect that.
  2. Change thresholds.
    Towards the top of the script you’ll be able to set the following thresholds which must all be met to exclude a placement:
    • MIN_IMPRESSIONS – the minimum impressions a placement must have to be examined by the script
    • MIN_CLICKS – the minimum number of clicks a placement must have to be examined by the script
    • CONV_RATE_THRESHOLD – the minimum conversion rate acceptable to you, the advertiser

      Using the default thresholds, any placement which has 25 or more clicks, 50 or more impressions and a conversion rate below the threshold of 10% will be excluded by adding it to the desired Placement Exclusion List.
  3. Add the script and set the interval but, as above, ensure you preview what the script will do before pushing it onto a live environment.

The full Placement Exclusion Script

This placement exclusion script is free to use and a good starting point for anyone using GDN already who has a simple conversion account setup. For more complicated scripts or for assistance buying traffic, contact us.

/**
 * @name Automatic Placement Exclusion for Display Ads 
 *
 * @overview The Automatic Placement Exclusions script analyzes the
 *     performance of your display ads across various placements, and then
 *     automatically excludes them from appearing for URLs that have
 *     underperformed based on Clicks, Conversions and Impressions.
 *     
 *
 * Hat-tip to the Google Ads Scripts Team, based upon https://developers.google.com/google-ads/scripts/docs/solutions/automatic-placement-exclusions
 *
 * @author Personally.co.uk
 * https://www.personally.co.uk/google-ads/placement-exclusion-script/
 * @version 1
 *
 * @changelog
 * - version 1.0
 *   - Released initial version.
 */

//--Setup--

	//--Thresholds--
	//Ignore placements which don't meet the following thresholds:
	var MIN_IMPRESSIONS = 50;
	var MIN_CLICKS = 25;
	//The conversion rate under which placements will be automatically excluded
	var CONV_RATE_THRESHOLD = '10.00%';
	
	//--Define your Placement Exclusion List which you must create separately--
	var excludedPlacementList = "Auto Placement (Scripts) - Performance";

//--End Setup--

function main() {
  CONV_RATE_THRESHOLD = parseFloat(CONV_RATE_THRESHOLD);
  var results = getReportResults();
  var ids = [];
  for (var id in results) {
    ids.push(id);
  }

  //remove .withCondition("Status = ENABLED") to work on all display campaigns, not just enabled ones
  var displayIterator = AdsApp.campaigns().withCondition("Status = ENABLED").withCondition("AdvertisingChannelType = DISPLAY").get(); 

  while (displayIterator.hasNext()) {
    var displayCampaign = displayIterator.next();
    var id = displayCampaign.getId();
    if (results.hasOwnProperty(id)) {
      var urls = results[id];
      for (var i = 0; i < urls.length; i++) {
          var sharedSet = AdsApp.excludedPlacementLists().withCondition("Name = '"+excludedPlacementList+"'").get().next();
          sharedSet.addExcludedPlacement(urls[i]);
      }
    }
  }
}

function getReportResults() {
  var query = 'SELECT CampaignId, Domain' +
    ' FROM URL_PERFORMANCE_REPORT' +
    ' WHERE Impressions >= ' + MIN_IMPRESSIONS +
    ' AND Clicks >= ' + MIN_CLICKS +
    ' AND ConversionRate < ' + (CONV_RATE_THRESHOLD / 100) +
    ' DURING LAST_7_DAYS';
  var report = AdsApp.report(query);
  var rows = report.rows();
  var results = {};
  while (rows.hasNext()) {
    var row = rows.next();
    var campaignId = row['CampaignId'];
    var url = row['Domain'];
    if (!results.hasOwnProperty(campaignId)) {
      results[campaignId] = [];
    }
    if (results[campaignId].indexOf(url) < 0) {
      results[campaignId].push(url);
    }
  }
  return results;
}

NOTE – Enabling the ‘New scripts experience’ beta will break this script. Keep the toggle off for it to work correctly.

Further Reading

If you would like to change the time frame the script considers, replace ‘LAST_7_DAYS’ inside the query with any of the following:

  • TODAY
  • YESTERDAY
  • LAST_7_DAYS
  • THIS_WEEK_SUN_TODAY
  • THIS_WEEK_MON_TODAY
  • LAST_WEEK
  • LAST_14_DAYS
  • LAST_30_DAYS
  • LAST_WEEK
  • LAST_BUSINESS_WEEK
  • LAST_WEEK_SUN_SAT
  • THIS_MONTH
  • LAST_MONTH

For a script to block placements which yield poor view-rate on video ads, see Google’s example here.

Disclaimer: Whilst we’ve researched and tested methods in this post and elsewhere on this website, care should be taken when automating any part of online advertising. This information is made available for educational purposes only and provided ‘as is’, no representations are made that the content is error-free. Furthermore, things often change at Bing, Google et al and another person/team may interpret/implement things differently with unexpected outcomes. We, as the company and individuals within it, will not be held responsible for any damages or losses through the use of such methods or advice on this website or elsewhere.

Use Google Ads Scripts at your own risk.

Personally

This Post Has 11 Comments

    1. Thanks Daniel. We’ll look to upload some more free Google Ads scripts in the coming weeks, is there anything in particular you’d like to see?

  1. Hi

    Getting this error:
    “Cannot retrieve the next object: iterator has reached the end. (file Code.gs, line 52)”

    1. This would occur if the Placement Exclusion List is either not yet created (go to Tools at the top of the Google Ads dashboard, select ‘Placement exclusion lists’ under the heading ‘Shared Library’ to create one) OR not correctly referenced in the code – look for the following line:

      var excludedPlacementList = "Auto Placement (Scripts) - Performance";

      In our example the Placement Exclusion List is called Auto Placement (Scripts) – Performance, ensure the script references whatever you have called yours.

  2. Thanks for sharing this bro. The last time I tried running display ads for a business servicing a small location (so I couldn’t used Placement targeting). Using only Interest or Topic targeting gave me horrible clicks and no signs up. I was frustrated because I didn’t have budget to waste through bad clicks everyday.
    With this I can set a easier conversion step like scroll depth and exclude placements with 3 – 5 clicks and no visitors scrolling up-to 25 percent of my page.

    What do you think?

    1. I think that’s a great use case. Would be good for longer sign-up forms…we’ve also seen similar in the content arbitrage space.

  3. I have one more question…
    the time frame the script considers,

    ‘LAST_7_DAYS

    Does this mean the script will only look at performances after 7 days?
    I want to set its to look at performance everyday?

    1. The script uses ‘LAST_7_DAYS’ by default and, as such, would collect performance data for any active placement in the last 7 days. As in the post, you can also use ‘TODAY’, ‘YESTERDAY’, ‘LAST_30_DAYS’ amongst others.

      I would run the script hourly (you can define this when you set it up – just like a cron job) with as large a timeframe as practical.

  4. Please bro… I created a placement exclusions list with the name
    Auto Placement (Scripts) – Performance,
    And changed the other thresholds value.

    But when i preview its doesn’t bring up any message and even when I run its after authorize…. It’s shows failed in the script dashboard. Is this script still working fine or is there something else I need to add?

  5. Here is the log report when getting from preview!

    03/08/2021 21:44:16 Exception: Call to GoogleAdsService.Search failed: Cannot select or filter on the following metrics: ‘conversions_from_interactions_rate'(could not support requested resources: ‘DETAIL_PLACEMENT_VIEW’), since metric is incompatible with the resource in the FROM clause or other selected segmenting resources.
    at adsapp_compiled:13589:120
    at adsapp_compiled:13594:9
    at pa (adsapp_compiled:210:15)
    at adsapp_compiled:218:20
    at YA.search (adsapp_compiled:13679:28)
    at EA.search (adsapp_compiled:13315:19)
    at FA.search (adsapp_compiled:13396:20)
    at OA.search (adsapp_compiled:13487:19)
    at yc (adsapp_compiled:933:17)
    at yc.next ()

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back To Top