/

Playbook: Using SEOmonitor to minimise Paid Search cannibalisation

In this playbook, we’ll walk you through creating a fully automated solution that dynamically adjusts your bidding—helping you avoid PPC and SEO cannibalisation and get the most out of your campaigns.

Introduction

Puck Stop is the UK’s largest ice hockey store located in Sheffield, home of the Sheffield Steelers. As an independent and family-run business getting the most out of their marketing spend is crucial to their success. Over the years they’ve worked with Evoluted to establish a strong organic presence on Google search. After investing in a new Shopify website, the business was keen to capitalise on the new sleek user experience by investing in Google Ads to amplify their brand further. However, they were concerned about the risk of traffic cannibalisation. 

Evoluted ingeniously utilised SEOmonitor’s API to power an automated solution that would dynamically pause and enable Google Ads keywords based on the daily rankings of organic keywords. While there are “out-of-the-box” software that provide similar solutions, this one comes at no extra cost for SEOmonitor users.

The introduction of the automated solution as part of an integrated Search strategy resulted in Puck Stop’s website benefitting from an 18% uplift in traffic and a 31% increase in revenue, as both Organic and Paid channels saw year-on-year growth.

What You Need Before Starting

  • SEOmonitor API access – this will allow us to pull the organic rankings
  • Google Sheets – this is where we’ll work our magic
  • Google Ads Access – this is needed to build the Google Ads Script
  • Javascript knowledge – we’ll need this for the Google Ads Script

Pulling The Data Together

In this section, we’ll guide you step-by-step through setting up your spreadsheet to track all your keyword rankings.

First, make your own copy of the template provided above.

Setup the SEOmonitor API

Use the following settings for your SEOmonitor Report:


Google Ads – Scripts & Labels

Below is the Google Ads Script, with the red indicating elements to change and the blue indicating elements to note.

The Google Sheet URL and the Organic Ranking threshold you want to use to determine when to turn off and on your keywords are the only aspects you need to change to make this script work.

[YOUR_GOOGLE_SHEET_URL] – Replace this with the URL to your copy of the Google Sheets template, being sure to remove the [ ]

Keyword Ranking List with Labels – The name of the Tab in the Google Sheet template that is being used within this script. If you change the Tab name, be sure to update this section to identically match the new Tab name.

[THE_ORGANIC_RANK_THRESHOLD_YOU_WANT_TO_PAUSE_YOUR_PPC_KEYWORD] – In this example, we used 2 as the organic rank when keywords would be paused, meaning any Google Ads keywords whose label matches an organic keyword ranking #1 or #2 would be paused. Make sure to remove the [ ]

Keyword rank 2 or less, disabling the PPC keyword – change the number in red to match the number you’ve chosen for [THE_ORGANIC_RANK_THRESHOLD_YOU_WANT_TO_PAUSE_YOUR_PPC_KEYWORD]

[THE_ORGANIC_RANK_THRESHOLD_YOU_WANT_TO_ENABLE_YOUR_PPC_KEYWORD] – In this example, we used 3 as the organic rank when keywords would be enabled, meaning any Google Ads keywords whose label matches an organic keyword ranking #3 or higher would be enabled.

Keyword rank 3 or greater, enabling the PPC keyword – change the number in red to match the number you’ve chosen for [THE_ORGANIC_RANK_THRESHOLD_YOU_WANT_TO_ENABLE_YOUR_PPC_KEYWORD]. Make sure to remove the [ ]

The Google Ads Script:

function main() {
  var sheetUrl =
    "[YOUR_GOOGLE_SHEET_URL]";
  var spreadsheet = SpreadsheetApp.openByUrl(sheetUrl);
  var sheet = spreadsheet.getSheetByName("Keyword Ranking List with Labels");
  var data = sheet.getDataRange().getValues();

  for (var i = 1; i < data.length; i++) {
    var keyword = data[i][0].toString();
    var organicRanking = parseInt(data[i][1]);
    var labelValue = data[i][2].toString();

    if (organicRanking <= [THE_ORGANIC_RANK_THRESHOLD_YOU_WANT_TO_PAUSE_YOUR_PPC_KEYWORD]) {
      Logger.log("Keyword rank 2 or less, disabling the PPC keyword");
      pauseKeywordWithMatchingLabel(keyword, labelValue);
    } else if (organicRanking >= [THE_ORGANIC_RANK_THRESHOLD_YOU_WANT_TO_ENABLE_YOUR_PPC_KEYWORD]) {
      Logger.log("Keyword rank 3 or greater, enabling the PPC keyword");
      enableKeywordWithMatchingLabel(keyword, labelValue);
    } else {
      Logger.log("Something unexpected happened");
    }
  }
}

function pauseKeywordWithMatchingLabel(keyword, labelValue) {
  if (labelExists(labelValue)) {
    // Find the label object based on the label name
    var labelIterator = AdsApp.labels()
      .withCondition("Name = '" + labelValue + "'")
      .get();

    if (labelIterator.hasNext()) {
      var label = labelIterator.next();

      // Get the keywords associated with the label
      var keywordIterator = label.keywords().get();

      while (keywordIterator.hasNext()) {
        var accountKeyword = keywordIterator.next();
        accountKeyword.pause();
      }
    }
  } else {
    Logger.log("Label '" + labelValue + "' not found. Skipping...");
  }
}

function enableKeywordWithMatchingLabel(keyword, labelValue) {
  if (labelExists(labelValue)) {
    // Find the label object based on the label name
    var labelIterator = AdsApp.labels()
      .withCondition("Name = '" + labelValue + "'")
      .get();

    if (labelIterator.hasNext()) {
      var label = labelIterator.next();

      // Get the keywords associated with the label
      var keywordIterator = label.keywords().get();

      while (keywordIterator.hasNext()) {
        var accountKeyword = keywordIterator.next();
        accountKeyword.enable();
      }
    }
  } else {
    Logger.log("Label '" + labelValue + "' not found. Skipping enabling...");
  }
}

function labelExists(labelValue) {
  var labelIterator = AdsApp.labels()
    .withCondition("Name CONTAINS_IGNORE_CASE '" + labelValue + "'")
    .get();
  return labelIterator.hasNext();
}

Google Ads Labels

Now we have the script ready, it’s time to get the labels ready. I advise doing this via Google Ads Editor. First you want to load up the account. 

Secondly, you want to go into the keyword view, and ensure you have all the necessary filters applied. I recommend filtering out any removed or paused campaigns and ad groups you no longer plan to use, or any campaigns you don’t want to be impacted by this tool.

Next you’ll want to copy and paste all the keywords from Google Ads Editor into a Google Sheet. Like so:

Within this spreadsheet, you’ll want to ensure there is a column titled “Labels”. You’ll then want to populate this column with values equal to one of the labels you’ve assigned in your SEOmonitor – Google Ads Keyword Automation Sheet.

Tip: If you’re unsure of which organic keyword to use as a label for a Google Ads keyword, check the keyword’s search term data, this may help you understand which Organic Keyword is most appropriate.

Once the labels have been applied within the Google Sheet, you’ll need to Copy and Paste the table of data back into Google Ads.

To do this, use the “Make multiple changes” tool in Google Ads Editor, while in the keyword tab view. Change the “Bulk Change Action” from “Add or update” to “Replace” and change “Destination” from “Use selected destinations” to “My data includes columns for campaigns and/or ad groups”.

  • This will ensure it updates your existing keywords, rather than adding new keywords to all campaigns or creating duplicate keywords.

If it all went smoothly, you’ll have a status screen showing similar to this:

If you don’t, no sweat, you can review the “Errors and warnings” in the bottom half before clicking on “Revert and cancel” and making amends.

Otherwise, click “Finish and review changes”, and check the results. The label values should be updated showing all the changes made.

If you’re happy, click on “keep all” in the top left and go click “Post” in the top right corner to post the results.

Time For Testing

Once all the labels have been applied, you can test the scripts in Google Ads.

Authorise twice, save the script with a name and Preview.

Check the results and then run. I recommend setting this to run daily in the morning after the API runs its update.

Check Performance

After you run the script the first time you should see keywords being paused and enabled – good work it’s operating as intended. However, we don’t know if it’s improving performance. For this, we’ll need to wait a couple of days and communicate with the Sales team and SEO teams to see if organic traffic is improving and if overall sales performance is stable or improving. We want to avoid seeing any non-seasonal and unexplained dips in sales, particularly from the Google Ads account. If this happens, check the performance of keywords utilising the script to see if performance dips correlate with keyword status changes.

Tracking within SEOmonitor

Now, create dynamic keyword groups within SEOmonitor:

  • First, set up a group filtering for keywords where Google Ads appear.
  • Then, create another group specifically filtering for keywords where your website is shown.

This approach lets you clearly monitor and compare keyword performance on SERPs both with and without Google Ads.

Conclusion

Using SEOmonitor’s API to automate PPC and SEO management helps agencies like Evoluted reduce channel cannibalisation, improve efficiency, and drive significant traffic and revenue growth—all within their current subscription, with no extra software costs.

About Evoluted

Evoluted is a certified B Corp™ award-winning full-service digital agency. We provide integrated web development and digital marketing services to our clients across the globe by dedicating time to understanding what makes a successful company tick to deliver client-first, value-driven solutions. Since 2006, we’ve approached each partnership as a natural extension of your team to ensure our solutions and strategies align with your business needs and objectives.

Chris Ridley

Chris Ridley

After a decade in the hospitality industry learning about customer service and importantly the difference between a lager and an IPA, Chris brought his care of people into digital marketing.
Over the last 6 years, he has worked his way up from being a marketing executive in a family-run business to Head of Paid Media at Evoluted where he is always looking for ways to utilise technology to best serve his clients. Chris is no stranger to the spotlight and loves to share his knowledge at prestigious conferences, including brightonSEO and Sheffield DM.

Inside this article