Skip to content

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.

By Gordon Geraghty·MIT Licence·Updated: 21 August 2026·BEGINNER·GitHub Mirror ↗

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

GAQL Landing Page 404 MonitorLandingPage404Monitor.jsjavascript

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 Licence

This 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.