📋 Framework Overview

This framework breaks down Google Ads management into seven distinct phases, each with clear objectives and deliverables. Use this as your north star when planning, launching, and optimizing campaigns.

Step 1: Campaign Strategy & Goal Setting

Objective: Define clear business goals and translate them into measurable campaign objectives.

What to do:

  • Identify your primary business goal (leads, sales, brand awareness, app installs)

  • Set specific KPI targets: CPA, ROAS, conversion volume, CTR benchmarks

  • Determine budget allocation across campaigns and ad groups

  • Map out customer journey stages and align ad messaging accordingly

  • Document your target audience: demographics, pain points, search intent

Deliverables:

  • Campaign brief document

  • KPI targets spreadsheet

  • Budget allocation plan

  • Audience persona profiles

Step 2: Keyword Research & Account Structure

Objective: Build a robust keyword foundation and logical account architecture.

What to do:

  • Conduct comprehensive keyword research using Google Keyword Planner, SEMrush, or similar tools

  • Organize keywords by theme, intent (informational, navigational, transactional), and match type

  • Create tightly themed ad groups (5-20 keywords per ad group)

  • Develop negative keyword lists at campaign and account level

  • Structure campaigns by product/service line, geography, or funnel stage

Deliverables:

  • Master keyword list with search volumes and CPC estimates

  • Account structure diagram

  • Negative keyword master list

  • Ad group mapping document

Step 3: Ad Copy & Creative Development

Objective: Write compelling ad copy that drives clicks and conversions.

What to do:

  • Write 3-5 ad variations per ad group (use Responsive Search Ads)

  • Incorporate target keywords in headlines and descriptions

  • Highlight unique value propositions, offers, and CTAs

  • Test different messaging angles: features vs. benefits, urgency vs. trust

  • Ensure ad copy matches landing page messaging

  • Add all relevant ad extensions (sitelinks, callouts, structured snippets, call extensions)

Deliverables:

  • Ad copy spreadsheet with all variations

  • Ad extensions library

  • Brand messaging guidelines

Step 4: Landing Page Setup & QA

Objective: Ensure landing pages are optimized for conversion and align with ad messaging.

What to do:

  • Review landing page load speed (target <3 seconds)

  • Verify message match between ads and landing pages

  • Check form functionality and tracking implementation

  • Ensure mobile responsiveness

  • Add conversion tracking pixels (Google Ads, Google Analytics 4)

  • Set up conversion goals in Google Ads

  • Test all CTAs and user flows

Deliverables:

  • Landing page QA checklist (completed)

  • Conversion tracking documentation

  • Page speed test results

Step 5: Campaign Launch & Initial Monitoring

Objective: Launch campaigns smoothly and catch any issues within the first 48-72 hours.

What to do:

  • Double-check budget settings, bid strategies, and targeting parameters

  • Verify conversion tracking is firing correctly

  • Monitor search term reports for irrelevant queries

  • Add negative keywords based on initial data

  • Check impression share and ad position metrics

  • Ensure ads are running (not paused or disapproved)

Deliverables:

  • Launch checklist (completed)

  • Initial performance snapshot

  • First batch of negative keywords

Step 6: Ongoing Optimization & Testing

Objective: Continuously improve campaign performance through data-driven optimizations.

What to do:

  • Review search term reports and add negative keywords

  • Pause underperforming keywords and ads

  • Test new ad copy variations

  • Adjust bids based on performance data

  • Expand winning keywords to new ad groups

  • Review audience insights and adjust targeting

  • Test landing page variations

  • Optimize Quality Scores (improve CTR, relevance, landing page experience)

Deliverables:

  • Weekly optimization reports

  • A/B test results documentation

  • Updated keyword and negative keyword lists

Step 7: Reporting & Strategic Review

Objective: Analyze performance, extract insights, and plan strategic adjustments.

What to do:

  • Compile monthly performance reports with KPI tracking

  • Analyze trends: what's working, what's not, and why

  • Calculate ROI and present business impact

  • Identify opportunities for expansion or budget reallocation

  • Review competitive landscape and adjust strategy

  • Document learnings and best practices for future campaigns

Deliverables:

  • Monthly performance report

  • Strategic recommendations deck

  • Updated campaign roadmap

Actionable Checklists

Pre-Launch Checklist

Campaign Setup

  • Campaign objectives and goals documented — Strategist/Account Manager — One-time

  • Budget allocated across campaigns — Strategist/Account Manager — One-time

  • Keyword research completed — PPC Specialist — One-time

  • Account structure finalized — PPC Specialist — One-time

  • Ad groups created with themed keywords — PPC Specialist — One-time

  • Negative keyword lists uploaded — PPC Specialist — One-time

Ad Copy & Extensions

  • Responsive Search Ads written (3-5 per ad group) — Copywriter/PPC Specialist — One-time

  • Ad extensions created (sitelinks, callouts, structured snippets) — PPC Specialist — One-time

  • Call extensions added with correct phone numbers — PPC Specialist — One-time

  • Ad copy reviewed for brand compliance — Account Manager — One-time

Landing Pages & Tracking

  • Landing pages created and optimized — Web Developer/Designer — One-time

  • Message match verified between ads and landing pages — PPC Specialist — One-time

  • Page load speed tested (<3 seconds) — Web Developer — One-time

  • Mobile responsiveness confirmed — Web Developer — One-time

  • Google Ads conversion tracking installed — PPC Specialist/Developer — One-time

  • Google Analytics 4 connected and configured — PPC Specialist/Developer — One-time

  • Conversion actions tested and verified — PPC Specialist — One-time

  • Form submissions and phone calls tracked — Developer — One-time

Final Checks

  • Bid strategy selected and configured — PPC Specialist — One-time

  • Budget pacing settings verified — PPC Specialist — One-time

  • Targeting parameters confirmed (location, language, devices) — PPC Specialist — One-time

  • Ad scheduling set (if applicable) — PPC Specialist — One-time

  • Client approval received — Account Manager — One-time

  • Launch date and time scheduled — PPC Specialist — One-time

Daily Management Checklist

Performance Monitoring

  • Check campaign spend vs. budget pacing — PPC Specialist — Daily (9 AM)

  • Review conversion data for anomalies — PPC Specialist — Daily (9 AM)

  • Monitor impression share and lost IS (budget/rank) — PPC Specialist — Daily (9 AM)

  • Check for disapproved ads or policy violations — PPC Specialist — Daily (9 AM)

  • Review automated alerts and notifications — PPC Specialist — Daily (9 AM)

Quick Optimizations

  • Add negative keywords from search terms report — PPC Specialist — Daily (11 AM)

  • Pause keywords with high spend and zero conversions — PPC Specialist — Daily (11 AM)

  • Respond to any client questions or concerns — Account Manager — Daily (as needed)

Weekly Optimization Checklist

Search Terms & Keywords

  • Full search terms report review — PPC Specialist — Weekly (Monday)

  • Add 10-20 new negative keywords — PPC Specialist — Weekly (Monday)

  • Identify and promote high-performing search terms to keywords — PPC Specialist — Weekly (Monday)

  • Pause keywords with poor Quality Scores (<4) or no impressions — PPC Specialist — Weekly (Monday)

Ad Performance

  • Review ad performance by CTR and conversion rate — PPC Specialist — Weekly (Tuesday)

  • Pause ads with CTR <50% of ad group average — PPC Specialist — Weekly (Tuesday)

  • Launch new ad copy variations for testing — Copywriter/PPC Specialist — Weekly (Tuesday)

  • Update ad extensions based on performance — PPC Specialist — Weekly (Tuesday)

Bid Management

  • Review keyword-level performance (CPA, ROAS, conversions) — PPC Specialist — Weekly (Wednesday)

  • Adjust bids on top-performing keywords (+10-20%) — PPC Specialist — Weekly (Wednesday)

  • Reduce bids on underperformers (-10-20%) — PPC Specialist — Weekly (Wednesday)

  • Review automated bidding strategy performance — PPC Specialist — Weekly (Wednesday)

Budget & Pacing

  • Analyze budget utilization across campaigns — PPC Specialist — Weekly (Thursday)

  • Reallocate budget from low to high performers — PPC Specialist/Account Manager — Weekly (Thursday)

  • Forecast spend to end of month — PPC Specialist — Weekly (Thursday)

Reporting

  • Generate weekly performance snapshot — PPC Specialist — Weekly (Friday)

  • Document key wins and optimizations — PPC Specialist — Weekly (Friday)

  • Share client-facing update (if required) — Account Manager — Weekly (Friday)

Post-Campaign Wrap-Up Checklist

Performance Analysis

  • Pull final campaign performance report — PPC Specialist — One-time

  • Calculate final ROAS, CPA, and other KPIs — PPC Specialist — One-time

  • Compare actual vs. target performance — PPC Specialist — One-time

  • Analyze top-performing keywords, ads, and audiences — PPC Specialist — One-time

  • Identify underperforming elements and root causes — PPC Specialist — One-time

Documentation

  • Compile master keyword list (winners and losers) — PPC Specialist — One-time

  • Document negative keyword additions — PPC Specialist — One-time

  • Save top-performing ad copy for future use — Copywriter/PPC Specialist — One-time

  • Screenshot best-performing landing pages — PPC Specialist — One-time

  • Create campaign post-mortem document — Account Manager — One-time

Client Deliverables

  • Prepare final campaign report with insights — Account Manager — One-time

  • Schedule client review meeting — Account Manager — One-time

  • Present findings and recommendations — Account Manager — One-time

  • Gather client feedback — Account Manager — One-time

Next Steps

  • Archive campaign or keep paused for future reactivation — PPC Specialist — One-time

  • Update account-level negative keyword lists — PPC Specialist — One-time

  • Apply learnings to active campaigns — PPC Specialist — One-time

  • Plan next campaign iteration or new initiatives — Strategist/Account Manager — One-time

Download the Excel Checklist

A companion spreadsheet is available to track task completion across your team.

Google_Ads_Optimization_Checklist.csv

Google_Ads_Optimization_Checklist.csv

9.09 KBCSV File

📖 Standard Operating Procedures (SOPs)

SOP: Keyword Research

Objective: Identify high-intent, relevant keywords to drive qualified traffic.

Frequency: One-time at campaign launch; quarterly refreshes

Tools Needed: Google Keyword Planner, SEMrush, Ahrefs, or similar

Steps:

  1. Brainstorm seed keywords — List 10-15 core terms related to your product/service

  2. Use keyword research tools — Input seed keywords into Google Keyword Planner or third-party tools

  3. Analyze search volume and competition — Filter for keywords with 100+ monthly searches and manageable CPC

  4. Group keywords by theme — Organize into logical ad groups (e.g., "running shoes for women," "best trail running shoes")

  5. Identify match types — Assign Exact, Phrase, or Broad Match Modifier based on intent

  6. Add long-tail variations — Include specific, high-intent queries (e.g., "buy Nike running shoes size 9")

  7. Research competitor keywords — Use SEMrush or SpyFu to see what competitors are bidding on

  8. Build negative keyword list — Identify irrelevant terms to exclude (e.g., "free," "cheap," "jobs")

  9. Document in master spreadsheet — Include columns for keyword, match type, search volume, CPC, ad group assignment

  10. Review and approve — Get sign-off from account manager or client before upload

Deliverable: Master keyword list with 100-500 keywords organized by ad group

SOP: Ad Copy Writing

Objective: Create compelling, high-CTR ad copy that drives conversions.

Frequency: One-time at launch; weekly for new variations

Steps:

  1. Review ad group keywords — Understand the theme and search intent

  2. Identify unique selling propositions — What makes your offer better? (price, quality, speed, guarantee)

  3. Write 15 headline variations — Include target keywords, benefits, offers, and CTAs

  4. Write 4 description variations — Expand on value props, include social proof or urgency

  5. Use dynamic keyword insertion (DKI) sparingly — Only where it makes sense grammatically

  6. Follow character limits — Headlines: 30 chars max; Descriptions: 90 chars max

  7. Pin critical elements — Pin your main headline or brand name to position 1 if needed

  8. Create 3-5 RSA combinations per ad group — Google will test variations automatically

  9. Add all relevant extensions — Sitelinks, callouts, structured snippets

  10. Review for brand compliance — Ensure tone, messaging, and claims align with brand guidelines

  11. Get approval — Review with client or account manager before launch

  12. Monitor ad strength — Aim for "Excellent" or "Good" ad strength ratings

Deliverable: 3-5 Responsive Search Ads per ad group with full ad extensions

SOP: Bid Management

Objective: Optimize bids to maximize conversions within target CPA or ROAS.

Frequency: Weekly for manual CPC; bi-weekly for automated strategies

Steps:

  1. Pull keyword performance report — Last 7-14 days of data (conversions, CPA, ROAS, CTR, Avg. Position)

  2. Identify top performers — Keywords with CPA below target and strong conversion volume

  3. Increase bids on winners — Raise bids by 10-20% to capture more volume

  4. Identify underperformers — Keywords with high spend, zero conversions, or CPA above target

  5. Decrease bids on losers — Lower bids by 10-20% or pause if consistently poor

  6. Review impression share — If IS Lost (Rank) is high, consider bid increases

  7. Check Quality Score — Low QS keywords may need ad copy or landing page improvements, not just bid changes

  8. Adjust for device performance — Increase/decrease mobile bid adjustments based on conversion data

  9. Monitor automated bid strategy performance — If using Target CPA or Maximize Conversions, review learning period and performance trends

  10. Document changes — Note all bid adjustments in optimization log

Deliverable: Updated keyword bids; optimization log with rationale

SOP: Landing Page QA

Objective: Ensure landing pages are conversion-optimized and technically sound.

Frequency: One-time before launch; monthly spot checks

Tools Needed: Google PageSpeed Insights, GTmetrix, Google Tag Assistant

Steps:

  1. Check page load speed — Test on desktop and mobile using PageSpeed Insights (target: <3 seconds)

  2. Verify mobile responsiveness — Test on multiple devices and screen sizes

  3. Review message match — Ensure headline and copy align with ad messaging

  4. Test form functionality — Submit test leads to verify form submissions work

  5. Check CTA visibility — Ensure primary CTA is above the fold and stands out

  6. Verify tracking implementation — Use Google Tag Assistant to confirm conversion tags fire correctly

  7. Test all links — Ensure no broken links or 404 errors

  8. Review trust signals — Check for security badges, testimonials, social proof

  9. Optimize images — Compress large images to improve load speed

  10. Run accessibility check — Ensure compliance with WCAG guidelines (contrast, alt text)

  11. Test across browsers — Chrome, Safari, Firefox, Edge

  12. Document findings — Create QA report with issues and fixes

Deliverable: QA report with pass/fail status and action items

SOP: Search Terms Report Review

Objective: Identify irrelevant queries and add negative keywords to improve efficiency.

Frequency: Daily for first week; then weekly

Steps:

  1. Pull search terms report — Last 7 days, all campaigns

  2. Filter by clicks or impressions — Focus on terms with meaningful volume

  3. Identify irrelevant queries — Flag searches that don't match intent (e.g., "free," "jobs," "DIY")

  4. Add negative keywords — Add at ad group, campaign, or account level depending on relevance

  5. Choose correct match type — Use Exact for specific terms, Phrase for broader exclusions

  6. Identify expansion opportunities — Promote high-performing search terms to keywords

  7. Flag quality issues — Note any terms that indicate poor keyword targeting

  8. Update negative keyword master list — Document all additions for future reference

  9. Review regularly — Repeat weekly to catch new irrelevant queries

  10. Monitor impact — Track how negative keywords improve CTR and reduce wasted spend

Deliverable: Updated negative keyword lists; list of search terms promoted to keywords

📊 KPI Dashboard

Core Metrics Definitions

Impressions

  • Definition: Number of times your ad was shown

  • Why it matters: Indicates reach and visibility

  • Target: Varies by campaign; monitor impression share

Clicks

  • Definition: Number of times users clicked your ad

  • Why it matters: Shows ad engagement and interest

  • Target: Varies by campaign; aim for consistent volume

CTR (Click-Through Rate)

  • Definition: (Clicks ÷ Impressions) × 100

  • Why it matters: Measures ad relevance and appeal

  • Target: 3-5% for search campaigns; 0.5-1% for display

  • Notion Formula: prop("Clicks") / prop("Impressions") * 100

CPC (Cost Per Click)

  • Definition: Total cost ÷ Total clicks

  • Why it matters: Shows how much you pay per click

  • Target: Varies by industry; aim to reduce over time

  • Notion Formula: prop("Cost") / prop("Clicks")

Conversions

  • Definition: Number of desired actions completed (purchases, leads, signups)

  • Why it matters: Direct measure of campaign effectiveness

  • Target: Based on business goals and budget

Conversion Rate

  • Definition: (Conversions ÷ Clicks) × 100

  • Why it matters: Shows how well your landing page converts traffic

  • Target: 2-5% for most industries; 10%+ for high-intent campaigns

  • Notion Formula: prop("Conversions") / prop("Clicks") * 100

CPA (Cost Per Acquisition)

  • Definition: Total cost ÷ Total conversions

  • Why it matters: Shows how much you pay per conversion

  • Target: Must be lower than customer lifetime value (LTV)

  • Notion Formula: prop("Cost") / prop("Conversions")

ROAS (Return on Ad Spend)

  • Definition: Revenue generated ÷ Ad spend

  • Why it matters: Measures profitability and ROI

  • Target: Minimum 4:1 for ecommerce; varies by business model

  • Notion Formula: prop("Revenue") / prop("Cost")

Quality Score

  • Definition: Google's 1-10 rating based on expected CTR, ad relevance, landing page experience

  • Why it matters: Higher QS = lower CPCs and better ad positions

  • Target: 7-10 (anything below 5 needs immediate attention)

Impression Share

  • Definition: (Impressions received ÷ Total eligible impressions) × 100

  • Why it matters: Shows how often your ad could have shown but didn't

  • Target: 80%+ for branded campaigns; 50-70% for competitive terms

  • Notion Formula: prop("Impressions") / prop("Eligible Impressions") * 100

Script 1: Pause Low-Quality Keywords

Purpose: Automatically pauses keywords with Quality Score below 4 to prevent wasted spend.

How to schedule: Set to run daily at 2 AM

// Pause Low Quality Score Keywords
function main() {
  var QUALITY_SCORE_THRESHOLD = 4;
  
  var keywordIterator = AdsApp.keywords()
    .withCondition("Status = ENABLED")
    .withCondition("QualityScore < " + QUALITY_SCORE_THRESHOLD)
    .get();
  
  var pausedCount = 0;
  
  while (keywordIterator.hasNext()) {
    var keyword = keywordIterator.next();
    keyword.pause();
    pausedCount++;
    Logger.log("Paused keyword: " + keyword.getText() + " (QS: " + keyword.getQualityScore() + ")");
  }
  
  Logger.log("Total keywords paused: " + pausedCount);
  
  // Send email notification
  if (pausedCount > 0) {
    MailApp.sendEmail({
      to: "[email protected]",
      subject: "Google Ads: " + pausedCount + " Low QS Keywords Paused",
      body: "Check Google Ads script logs for details."
    });
  }
}

Script 2: Pause Ads with High Spend and No Conversions

Purpose: Pauses ads that have spent more than $50 with zero conversions in the last 30 days.

How to schedule: Set to run weekly on Monday mornings

// Pause High-Spend, Zero-Conversion Ads
function main() {
  var SPEND_THRESHOLD = 50;
  var DATE_RANGE = "LAST_30_DAYS";
  
  var adIterator = AdsApp.ads()
    .withCondition("Status = ENABLED")
    .withCondition("Conversions = 0")
    .withCondition("Cost > " + SPEND_THRESHOLD)
    .forDateRange(DATE_RANGE)
    .get();
  
  var pausedCount = 0;
  
  while (adIterator.hasNext()) {
    var ad = adIterator.next();
    var stats = ad.getStatsFor(DATE_RANGE);
    ad.pause();
    pausedCount++;
    Logger.log("Paused ad in campaign: " + ad.getCampaign().getName() + 
               " | Spend: $" + stats.getCost().toFixed(2) + " | Conversions: 0");
  }
  
  Logger.log("Total ads paused: " + pausedCount);
  
  if (pausedCount > 0) {
    MailApp.sendEmail({
      to: "[email protected]",
      subject: "Google Ads: " + pausedCount + " Zero-Conversion Ads Paused",
      body: "Check logs for details on which ads were paused."
    });
  }
}

Script 3: Daily Email Performance Summary

Purpose: Sends a daily email with key metrics from yesterday's performance.

How to schedule: Set to run daily at 8 AM

// Daily Performance Email Summary
function main() {
  var DATE_RANGE = "YESTERDAY";
  
  var accountStats = AdsApp.currentAccount().getStatsFor(DATE_RANGE);
  var impressions = accountStats.getImpressions();
  var clicks = accountStats.getClicks();
  var cost = accountStats.getCost();
  var conversions = accountStats.getConversions();
  var ctr = accountStats.getCtr();
  var cpa = conversions > 0 ? cost / conversions : 0;
  
  var emailBody = "Google Ads Daily Performance Summary - " + DATE_RANGE + "\n\n";
  emailBody += "Impressions: " + impressions.toLocaleString() + "\n";
  emailBody += "Clicks: " + clicks.toLocaleString() + "\n";
  emailBody += "CTR: " + (ctr * 100).toFixed(2) + "%\n";
  emailBody += "Cost: $" + cost.toFixed(2) + "\n";
  emailBody += "Conversions: " + conversions + "\n";
  emailBody += "CPA: $" + cpa.toFixed(2) + "\n";
  
  MailApp.sendEmail({
    to: "[email protected]",
    subject: "Google Ads Daily Summary - " + new Date().toLocaleDateString(),
    body: emailBody
  });
  
  Logger.log(emailBody);
}

Script 4: Label Top-Performing Search Queries

Purpose: Automatically labels search queries with 3+ conversions and CPA below target as "Top Performer".

How to schedule: Set to run weekly on Wednesdays

// Label Top-Performing Search Queries
function main() {
  var MIN_CONVERSIONS = 3;
  var MAX_CPA = 50; // Adjust to your target CPA
  var LABEL_NAME = "Top Performer";
  
  // Create label if it doesn't exist
  if (!AdsApp.labels().withCondition("Name = '" + LABEL_NAME + "'").get().hasNext()) {
    AdsApp.createLabel(LABEL_NAME);
  }
  
  var searchQueryReport = AdsApp.report(
    "SELECT Query, Conversions, Cost, CampaignName " +
    "FROM SEARCH_QUERY_PERFORMANCE_REPORT " +
    "WHERE Conversions >= " + MIN_CONVERSIONS + " " +
    "AND Cost / Conversions <= " + MAX_CPA + " " +
    "DURING LAST_30_DAYS"
  );
  
  var rows = searchQueryReport.rows();
  var labeledCount = 0;
  
  while (rows.hasNext()) {
    var row = rows.next();
    Logger.log("Top performer: " + row["Query"] + " | Conversions: " + row["Conversions"] + 
               " | CPA: $" + (row["Cost"] / row["Conversions"]).toFixed(2));
    labeledCount++;
  }
  
  Logger.log("Total top-performing queries identified: " + labeledCount);
  
  MailApp.sendEmail({
    to: "[email protected]",
    subject: "Google Ads: " + labeledCount + " Top Performers Identified",
    body: "Check script logs for query details."
  });
}

Script 5: Auto-Add Negative Keywords Across Campaigns

Purpose: Scans search terms and adds common negative keywords to all campaigns.

How to schedule: Set to run daily at 3 AM

// Auto-Add Negative Keywords
function main() {
  var NEGATIVE_KEYWORDS = ["free", "cheap", "jobs", "career", "salary", "diy", "tutorial", "download"];
  
  var campaignIterator = AdsApp.campaigns()
    .withCondition("Status = ENABLED")
    .get();
  
  var addedCount = 0;
  
  while (campaignIterator.hasNext()) {
    var campaign = [campaignIterator.next](<http://campaignIterator.next>)();
    
    for (var i = 0; i < NEGATIVE_KEYWORDS.length; i++) {
      var negativeKeyword = NEGATIVE_KEYWORDS[i];
      
      // Check if negative keyword already exists
      var existingNegatives = campaign.negativeKeywords()
        .withCondition("Text = '" + negativeKeyword + "'")
        .get();
      
      if (!existingNegatives.hasNext()) {
        campaign.createNegativeKeyword("[" + negativeKeyword + "]"); // Exact match
        addedCount++;
        Logger.log("Added negative keyword '" + negativeKeyword + "' to campaign: " + campaign.getName());
      }
    }
  }
  
  Logger.log("Total negative keywords added: " + addedCount);
  
  if (addedCount > 0) {
    MailApp.sendEmail({
      to: "[[email protected]](<mailto:[email protected]>)",
      subject: "Google Ads: " + addedCount + " Negative Keywords Added",
      body: "Check logs for details."
    });
  }
}

Script 6: Smart Bid Adjustment for High & Low Performing Keywords

Purpose: Automatically increases bids on high performers and decreases bids on underperformers.

How to schedule: Set to run daily at 1 AM

// Smart Bid Adjustment Script
function main() {
  var MIN_CONVERSIONS = 2;
  var TARGET_CPA = 50; // Adjust to your target
  var BID_INCREASE = 0.15; // 15% increase
  var BID_DECREASE = 0.15; // 15% decrease
  var MIN_SPEND = 20; // Minimum spend to consider
  
  var keywordIterator = AdsApp.keywords()
    .withCondition("Status = ENABLED")
    .forDateRange("LAST_14_DAYS")
    .get();
  
  var increasedCount = 0;
  var decreasedCount = 0;
  
  while (keywordIterator.hasNext()) {
    var keyword = [keywordIterator.next](<http://keywordIterator.next>)();
    var stats = keyword.getStatsFor("LAST_14_DAYS");
    var conversions = stats.getConversions();
    var cost = stats.getCost();
    var currentBid = keyword.bidding().getCpc();
    
    // High performer: Increase bid
    if (conversions >= MIN_CONVERSIONS && (cost / conversions) < TARGET_CPA) {
      var newBid = currentBid * (1 + BID_INCREASE);
      keyword.bidding().setCpc(newBid);
      increasedCount++;
      Logger.log("Increased bid for: " + keyword.getText() + " | Old: $" + currentBid.toFixed(2) + 
                 " | New: $" + newBid.toFixed(2));
    }
    
    // Low performer: Decrease bid
    if (conversions === 0 && cost > MIN_SPEND) {
      var newBid = currentBid * (1 - BID_DECREASE);
      keyword.bidding().setCpc(newBid);
      decreasedCount++;
      Logger.log("Decreased bid for: " + keyword.getText() + " | Old: $" + currentBid.toFixed(2) + 
                 " | New: $" + newBid.toFixed(2));
    }
  }
  
  Logger.log("Bids increased: " + increasedCount + " | Bids decreased: " + decreasedCount);
  
  MailApp.sendEmail({
    to: "[[email protected]](<mailto:[email protected]>)",
    subject: "Google Ads Bid Adjustments: +" + increasedCount + " / -" + decreasedCount,
    body: "Check logs for keyword-level details."
  });
}

Purpose: Promotes high-performing search terms into keywords.

How to schedule: Set to run weekly on Fridays

// Auto-Expand Winning Search Terms
function main() {
  var MIN_CONVERSIONS = 3;
  var MAX_CPA = 50; // Adjust to your target CPA
  
  var searchQueryReport = [AdsApp.report](<http://AdsApp.report>)(
    "SELECT Query, Conversions, Cost, CampaignId, AdGroupId " +
    "FROM SEARCH_QUERY_PERFORMANCE_REPORT " +
    "WHERE Conversions >= " + MIN_CONVERSIONS + " " +
    "AND Cost / Conversions <= " + MAX_CPA + " " +
    "DURING LAST_30_DAYS"
  );
  
  var rows = searchQueryReport.rows();
  var addedCount = 0;
  
  while (rows.hasNext()) {
    var row = [rows.next](<http://rows.next>)();
    var query = row["Query"];
    var adGroupId = row["AdGroupId"];
    
    var adGroup = AdsApp.adGroups()
      .withIds([adGroupId])
      .get()
      .next();
    
    // Check if keyword already exists
    var existingKeywords = adGroup.keywords()
      .withCondition("Text = '" + query + "'")
      .get();
    
    if (!existingKeywords.hasNext()) {
      adGroup.newKeywordBuilder()
        .withText(query)
        .build();
      addedCount++;
      Logger.log("Added new keyword: '" + query + "' to ad group: " + adGroup.getName());
    }
  }
  
  Logger.log("Total new keywords added: " + addedCount);
  
  if (addedCount > 0) {
    MailApp.sendEmail({
      to: "[[email protected]](<mailto:[email protected]>)",
      subject: "Google Ads: " + addedCount + " Winning Search Terms Promoted",
      body: "Check logs for details."
    });
  }
}

Script 8: Budget Rebalancer

Purpose: Reallocates budget from underperforming to top-performing campaigns.

How to schedule: Set to run weekly on Mondays

// Budget Rebalancer Script
function main() {
  var BUDGET_CHANGE = 0.10; // 10% adjustment
  var MIN_SPEND = 100; // Minimum spend to consider
  
  var campaignData = [];
  
  var campaignIterator = AdsApp.campaigns()
    .withCondition("Status = ENABLED")
    .forDateRange("LAST_14_DAYS")
    .get();
  
  // Collect campaign performance data
  while (campaignIterator.hasNext()) {
    var campaign = [campaignIterator.next](<http://campaignIterator.next>)();
    var stats = campaign.getStatsFor("LAST_14_DAYS");
    var cost = stats.getCost();
    var conversions = stats.getConversions();
    var cpa = conversions > 0 ? cost / conversions : 999999;
    
    if (cost >= MIN_SPEND) {
      campaignData.push({
        campaign: campaign,
        cpa: cpa,
        conversions: conversions,
        cost: cost
      });
    }
  }
  
  // Sort by CPA (ascending)
  campaignData.sort(function(a, b) { return [a.cpa](<http://a.cpa>) - [b.cpa](<http://b.cpa>); });
  
  var topPerformers = campaignData.slice(0, Math.ceil(campaignData.length * 0.3));
  var bottomPerformers = campaignData.slice(-Math.ceil(campaignData.length * 0.3));
  
  // Increase budget for top performers
  for (var i = 0; i < topPerformers.length; i++) {
    var campaign = topPerformers[i].campaign;
    var currentBudget = campaign.getBudget().getAmount();
    var newBudget = currentBudget * (1 + BUDGET_CHANGE);
    campaign.getBudget().setAmount(newBudget);
    Logger.log("Increased budget for: " + campaign.getName() + " | Old: $" + currentBudget.toFixed(2) + 
               " | New: $" + newBudget.toFixed(2));
  }
  
  // Decrease budget for bottom performers
  for (var j = 0; j < bottomPerformers.length; j++) {
    var campaign = bottomPerformers[j].campaign;
    var currentBudget = campaign.getBudget().getAmount();
    var newBudget = currentBudget * (1 - BUDGET_CHANGE);
    campaign.getBudget().setAmount(newBudget);
    Logger.log("Decreased budget for: " + campaign.getName() + " | Old: $" + currentBudget.toFixed(2) + 
               " | New: $" + newBudget.toFixed(2));
  }
  
  MailApp.sendEmail({
    to: "[[email protected]](<mailto:[email protected]>)",
    subject: "Google Ads: Budget Rebalanced Across Campaigns",
    body: "Check logs for campaign-level changes."
  });
}

Script 9: Quality Score Recovery Script

Purpose: Flags keywords with low Quality Score components and emails recommendations.

How to schedule: Set to run weekly on Tuesdays

// Quality Score Recovery Script
function main() {
  var LOW_QS_THRESHOLD = 5;
  
  var report = [AdsApp.report](<http://AdsApp.report>)(
    "SELECT CampaignName, AdGroupName, Criteria, QualityScore, " +
    "CreativeQualityScore, SearchPredictedCtr, PostClickQualityScore " +
    "FROM KEYWORDS_PERFORMANCE_REPORT " +
    "WHERE QualityScore < " + LOW_QS_THRESHOLD + " " +
    "AND Status = ENABLED " +
    "DURING LAST_30_DAYS"
  );
  
  var rows = report.rows();
  var issues = [];
  
  while (rows.hasNext()) {
    var row = [rows.next](<http://rows.next>)();
    var keyword = row["Criteria"];
    var qs = row["QualityScore"];
    var expectedCtr = row["SearchPredictedCtr"];
    var adRelevance = row["CreativeQualityScore"];
    var lpExperience = row["PostClickQualityScore"];
    
    var recommendations = [];
    
    if (expectedCtr === "Below average" || expectedCtr === "1") {
      recommendations.push("Improve ad copy CTR");
    }
    if (adRelevance === "Below average" || adRelevance === "1") {
      recommendations.push("Improve ad relevance to keyword");
    }
    if (lpExperience === "Below average" || lpExperience === "1") {
      recommendations.push("Improve landing page experience");
    }
    
    issues.push({
      keyword: keyword,
      qs: qs,
      fixes: recommendations.join(", ")
    });
  }
  
  if (issues.length > 0) {
    var emailBody = "Quality Score Issues Detected:\\n\\n";
    
    for (var i = 0; i < issues.length; i++) {
      emailBody += "Keyword: " + issues[i].keyword + " (QS: " + issues[i].qs + ")\\n";
      emailBody += "Recommended fixes: " + issues[i].fixes + "\\n\\n";
    }
    
    MailApp.sendEmail({
      to: "[[email protected]](<mailto:[email protected]>)",
      subject: "Google Ads: " + issues.length + " Low Quality Score Keywords Flagged",
      body: emailBody
    });
    
    Logger.log(emailBody);
  } else {
    Logger.log("No low QS keywords found.");
  }
}

Script 10: Ad Extension Checker

Purpose: Scans campaigns for missing or underperforming ad extensions.

How to schedule: Set to run daily at 9 AM

// Ad Extension Health Check Script
function main() {
  var issues = [];
  
  var campaignIterator = AdsApp.campaigns()
    .withCondition("Status = ENABLED")
    .get();
  
  while (campaignIterator.hasNext()) {
    var campaign = [campaignIterator.next](<http://campaignIterator.next>)();
    var campaignName = campaign.getName();
    
    // Check for sitelinks
    var sitelinks = campaign.extensions().sitelinks().get();
    if (!sitelinks.hasNext()) {
      issues.push(campaignName + ": Missing sitelinks");
    }
    
    // Check for callouts
    var callouts = campaign.extensions().callouts().get();
    if (!callouts.hasNext()) {
      issues.push(campaignName + ": Missing callouts");
    }
    
    // Check for structured snippets
    var snippets = campaign.extensions().snippets().get();
    if (!snippets.hasNext()) {
      issues.push(campaignName + ": Missing structured snippets");
    }
    
    // Check for phone extensions
    var phoneNumbers = campaign.extensions().phoneNumbers().get();
    if (!phoneNumbers.hasNext()) {
      issues.push(campaignName + ": Missing call extensions");
    }
  }
  
  if (issues.length > 0) {
    var emailBody = "Ad Extension Issues Detected:\\n\\n";
    
    for (var i = 0; i < issues.length; i++) {
      emailBody += issues[i] + "\\n";
    }
    
    emailBody += "\\nPlease review and add missing extensions to improve ad performance.";
    
    MailApp.sendEmail({
      to: "[[email protected]](<mailto:[email protected]>)",
      subject: "Google Ads: " + issues.length + " Extension Issues Found",
      body: emailBody
    });
    
    Logger.log(emailBody);
  } else {
    Logger.log("All campaigns have complete ad extensions.");
  }
}

🎯 How to Use This Framework

  1. Bookmark this page — Keep it accessible for daily reference

  2. Customize to your needs — Adjust KPI targets, script thresholds, and checklists based on your campaigns

  3. Schedule scripts in Google Ads — Go to Tools > Bulk Actions > Scripts, paste code, and set frequency

  4. Review weekly — Use the checklists to ensure nothing slips through the cracks

  5. Iterate and improve — Track what works, document learnings, and refine your approach

Questions or feedback? Use this framework as your foundation and adapt as you scale your Google Ads expertise.