Stop Paying Twice: A Free Tool To Eliminate Search Cannibalisation
Reduce search traffic cannibalisation and boost ROI through the power of automation
Managing PPC and SEO efforts simultaneously is essential… but it can be challenging.
Aligning these two channels is crucial for maximising your reach and ensuring the best Return on Investment from your marketing budget. One common challenge many businesses face is the friction between SEO and PPC caused by the risk of paid traffic stealing organic traffic and essentially causing the business to pay twice for the traffic.
Evoluted’s free SEOMonitor Adsync tool (SEOMonitor subscription required) dynamically adjusts your Google Ads keywords based on your website’s organic rankings and eliminates the threat of search cannibalisation.
In this article, we’ll outline how the tool works and walk you through the setup so you can implement it yourself.

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
Google Ads Editor - a free offline tool for making bulk changes in Google Ads
Javascript knowledge - we’ll need this for the Google Ads Script
Pulling The Data Together:
Before getting stuck into the script, you'll need to create a Google Sheet to host all your organic keyword rankings.
First, make a copy of our SEOMonitor Adsync Script template.
Once you have a copy of the Google Sheets template, you'll need to setup the SEOMonitor API
Use the following settings for your SEOMonitor Report:

Google Ads Setup
Google Ads Script
In this section, you'll creating the Google Ads script (javascript) and labels to automatically label and enable/pause Google Ads keywords.
Below is the Google Ads Script, followed by a list of elements in square brackets [ ]
which you will need to change, and other elements of the script which are worthy of note:
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();
// Check if the label starts with "SERP - "
if (labelValue.startsWith("SERP - ")) {
if (organicRanking <= [THE_ORGANIC_RANK_THRESHOLD_YOU_WANT_TO_PAUSE_YOUR_PPC_KEYWORD])) {
Logger.log("Keyword '" + keyword + "' has 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 '" + keyword + "' has rank 3 or greater. Enabling the PPC keyword.");
enableKeywordWithMatchingLabel(keyword, labelValue);
} else {
Logger.log("Unexpected ranking for keyword: " + keyword);
}
} else {
Logger.log("Label '" + labelValue + "' does not start with 'SERP - '. Skipping...");
}
}
}
function pauseKeywordWithMatchingLabel(keyword, labelValue) {
if (labelExists(labelValue)) {
var labelIterator = AdsApp.labels()
.withCondition("Name = '" + labelValue + "'")
.get();
if (labelIterator.hasNext()) {
var label = labelIterator.next();
var keywordIterator = label.keywords().get();
while (keywordIterator.hasNext()) {
var accountKeyword = keywordIterator.next();
accountKeyword.pause();
Logger.log("Paused keyword: " + accountKeyword.getText());
}
}
} else {
Logger.log("Label '" + labelValue + "' not found. Skipping...");
}
}
function enableKeywordWithMatchingLabel(keyword, labelValue) {
if (labelExists(labelValue)) {
var labelIterator = AdsApp.labels()
.withCondition("Name = '" + labelValue + "'")
.get();
if (labelIterator.hasNext()) {
var label = labelIterator.next();
var keywordIterator = label.keywords().get();
while (keywordIterator.hasNext()) {
var accountKeyword = keywordIterator.next();
accountKeyword.enable();
Logger.log("Enabled keyword: " + accountKeyword.getText());
}
}
} else {
Logger.log("Label '" + labelValue + "' not found. Skipping enabling...");
}
}
function labelExists(labelValue) {
var labelIterator = AdsApp.labels().get();
while (labelIterator.hasNext()) {
var label = labelIterator.next();
if (label.getName() === labelValue) {
return true;
}
}
return false;
}
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 [ ]
[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 [ ]
[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. Make 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.
// Check if the label starts with "SERP - "
- To distinguish the keyword labels we apply for this tool from your other keyword labels, we have added the prefix SERP -
to our labels. This will help prevent any other labels being used from interfering with this tool. The Google Sheet template already has the SERP -
prefix applied.
"Keyword '" + keyword + "' has rank 2 or less. Disabling the PPC keyword."
- change the number to match the number you’ve chosen for [THE_ORGANIC_RANK_THRESHOLD_YOU_WANT_TO_PAUSE_YOUR_PPC_KEYWORD]
.
"Keyword '" + keyword + "' has rank 3 or greater. Enabling the PPC keyword."
- change the number to match the number you’ve chosen for [THE_ORGANIC_RANK_THRESHOLD_YOU_WANT_TO_ENABLE_YOUR_PPC_KEYWORD]
.
Google Ads Labels
Now we have the script ready, it’s time to get the labels ready.
I’ll admit this does require some manual work but trust me it’s the only bit and it’s worth it!
I advise doing this via Google Ads Editor. First, you want to load up the Google Ads account.

Next up, 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.
Once your filters are in place, 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 SEO Monitor - 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 the number of "Keyword" entry types changes, and no errors or warnings.
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.
Ready To Transform Your Digital Strategy?
At Evoluted, we’re passionate about leveraging technology to optimise your digital marketing efforts.
If you’re ready to eliminate PPC and SEO cannibalisation and drive better performance across your campaigns, contact us to discuss how we can work together to take your marketing to the next level.