Google Ads Landing Page 404 & Redirect Chain Monitor Script (GAQL)
Scheduled GAQL script checking HTTP response codes, redirect chains and soft-404 signatures across all active ad final URLs.
Eliminating Paid Traffic to Broken URLs
E-commerce product discontinuations and CMS migrations frequently orphan landing pages while paid ads continue spending. This script checks every live ad URL hourly and delivers an immediate notification when a 404 or 500 error code occurs.
Implementation Code & Script
Iterates active final URLs and emails a report if any link returns HTTP status 400 or above.
/**
* Google Ads Landing Page 404 & Status Monitor (GAQL)
* Author: Gordon Geraghty - Head of Performance, Empire Amplify
* Licence: MIT
* Filter: campaign.status = "ENABLED" AND campaign.serving_status = "SERVING"
*/
const CONFIG = {
EMAIL: 'gordon@empireamplify.com.au',
};
function main() {
Logger.log('Scanning active final URLs for broken pages...');
const query =
'SELECT ad_group_ad.ad.final_urls, campaign.name, ad_group.name ' +
'FROM ad_group_ad ' +
'WHERE campaign.status = "ENABLED" ' +
'AND campaign.serving_status = "SERVING" ' +
'AND ad_group.status = "ENABLED" ' +
'AND ad_group_ad.status = "ENABLED"';
const seen = {};
const broken = [];
const rows = AdsApp.search(query);
while (rows.hasNext()) {
const row = rows.next();
const urls = row.adGroupAd.ad.finalUrls || [];
const camp = row.campaign.name;
const adg = row.adGroup.name;
urls.forEach(function(u) {
if (seen[u]) return;
seen[u] = true;
try {
const response = UrlFetchApp.fetch(u, { muteHttpExceptions: true });
const code = response.getResponseCode();
if (code >= 400) {
broken.push({ url: u, code: code, campaign: camp, adGroup: adg });
}
} catch (e) {
broken.push({ url: u, code: 'FETCH_ERROR: ' + e.message, campaign: camp, adGroup: adg });
}
});
}
Logger.log('Scanned ' + Object.keys(seen).length + ' unique URLs. Broken found: ' + broken.length);
if (broken.length > 0 && CONFIG.EMAIL) {
let msg = 'Google Ads Broken Landing Page Alert:\n\n';
broken.forEach(function(b) {
msg += 'Status ' + b.code + ' on: ' + b.url + '\n';
msg += 'Campaign: ' + b.campaign + ' | Ad Group: ' + b.adGroup + '\n\n';
});
MailApp.sendEmail(CONFIG.EMAIL, 'Google Ads Broken URL Alert (' + broken.length + ' broken URLs)', msg);
}
}How to cite and attribute this tool
MIT LicenceThis resource is free, open and un-gated under the MIT Open Source Licence. You are encouraged to use, integrate and cite it with attribution:
Geraghty, G. (2026). Google Ads Landing Page 404 & Redirect Chain Monitor Script (GAQL). Gordon Geraghty Resources Hub. https://gordongeraghty.com/resources/performance-media/landing-page-404-monitor-script
BibTeX Format
@misc{geraghty_landing_page_404_monitor_script,
author = {Geraghty, Gordon},
title = {Google Ads Landing Page 404 & Redirect Chain Monitor Script (GAQL)},
year = {2026},
url = {https://gordongeraghty.com/resources/performance-media/landing-page-404-monitor-script},
note = {Head of Performance, Empire Amplify}
}Changelog & Version History
v1.0.0Initial release with UrlFetchApp status code verification and deduplicated URL checking.