{"id":13319,"plugin_id":"plugin_asdk_app_698a0208e7d881919cc8d52147cb0331","kind":"skill","collection_source":null,"comparison_source":null,"observed_at":"2026-09-30T23:07:18.572Z","digest":"fcd53812e3019eeb997be407b6abab1fbd30025747f1a46d081ac0c2f55e510d","against":null,"payload":{"name":"google-ads-search-campaign-builder","description":"This skill should be used when the user asks to \"build a Search campaign\", \"write RSA ad copy\", \"improve Ad Strength\", \"set up sitelinks and callouts\", or mentions \"lead generation campaign\", \"call extensions\", \"lead forms\", or \"search campaign structure\". Do NOT use for: Performance Max campaigns (use performance-max-optimizer), Shopping campaigns (use shopping-campaign-structure-advisor), bid strategy selection (use bid-strategy-selector).","included_files":[{"relative_path":"references/api-patterns.md","size_in_bytes":1529},{"relative_path":"references/decision-trees.md","size_in_bytes":953}],"skill_md_contents":"---\nname: google-ads-search-campaign-builder\ndescription: \"This skill should be used when the user asks to \\\"build a Search campaign\\\", \\\"write RSA ad copy\\\", \\\"improve Ad Strength\\\", \\\"set up sitelinks and callouts\\\", or mentions \\\"lead generation campaign\\\", \\\"call extensions\\\", \\\"lead forms\\\", or \\\"search campaign structure\\\". Do NOT use for: Performance Max campaigns (use performance-max-optimizer), Shopping campaigns (use shopping-campaign-structure-advisor), bid strategy selection (use bid-strategy-selector).\"\n---\n# Search Campaign Builder\n\nComplete guide for setting up high-performance Google Ads Search campaigns specifically for lead generation with RSA best practices and full ad extensions setup.\n\n\n\n## 2026 Updates: AI Max + Broad Match + Smart Bidding\n\n### AI Max Search Campaign Type (2026)\nAI Max is a new Search campaign subtype that combines RSA ad serving with expanded keyword matching powered by Google AI. Key differences from standard Search:\n\n- Automatically matches to relevant queries beyond your keyword list\n- Uses landing page and asset content to find additional traffic\n- Requires: Smart Bidding (tCPA or Max Conversions), RSA with 8+ headlines\n- URL expansion: Google may direct to most relevant landing page\n- Best for: advertisers with strong conversion data who want to scale Search\n\nTo create an AI Max campaign, set `advertising_channel_sub_type = 'SEARCH_EXPRESS'` in API v23+. Note: `url_expansion_opt_out` was removed in v22; URL expansion control is now via `final_url_expansion_opt_out` at the campaign level.\n\n### Broad Match + Smart Bidding (Google's 2026 Recommendation)\nGoogle's official recommendation: use **broad match keywords paired with Smart Bidding** (tCPA or Max Conversions) rather than exact+phrase-heavy structures. Smart Bidding's signals prevent broad match from serving on irrelevant queries.\n\nDecision guide:\n- Account has <30 conversions/month: Start with exact+phrase, add broad later\n- Account has 30-100 conversions/month: Mix phrase + broad with tCPA\n- Account has >100 conversions/month: Broad match + tCPA is recommended, fewer ad groups needed\n\n### GAQL: Audit Search Campaign Health\n\n```sql\nSELECT campaign.name, campaign.status, campaign.bidding_strategy_type,\n    ad_group.name, metrics.impressions, metrics.clicks,\n    metrics.cost_micros, metrics.conversions,\n    metrics.search_impression_share, metrics.search_top_impression_share\nFROM ad_group\nWHERE campaign.advertising_channel_type = 'SEARCH'\nAND campaign.status = 'ENABLED'\nAND segments.date DURING LAST_30_DAYS\nORDER BY metrics.cost_micros DESC\nLIMIT 50\n```\n\n```sql\n-- Check search terms quality (match type performance)\nSELECT campaign.name, search_term_view.search_term,\n    search_term_view.status, segments.keyword.ad_group_criterion,\n    metrics.impressions, metrics.clicks, metrics.conversions,\n    metrics.cost_micros\nFROM search_term_view\nWHERE campaign.advertising_channel_type = 'SEARCH'\nAND segments.date DURING LAST_30_DAYS\nORDER BY metrics.cost_micros DESC\nLIMIT 100\n```\n\n## Campaign Structure for Lead Gen\n\n### Recommended Account Structure\n\n```\nLEAD GEN ACCOUNT STRUCTURE\n══════════════════════════\n\nCAMPAIGN 1: Brand\n├── Ad Group: Brand Exact\n│   ├── [company name]\n│   ├── [brand + service]\n│   └── High bid, maximize conversions\n├── Budget: 10-15% of total\n└── Goal: Capture branded intent\n\nCAMPAIGN 2: High-Intent Non-Brand\n├── Ad Group: Service + Action\n│   ├── \"[service] request\"\n│   ├── \"[service] quote\"\n│   └── \"[service] contact\"\n├── Ad Group: Service + Urgency\n│   ├── \"[service] today\"\n│   ├── \"[service] immediate\"\n│   └── \"[service] now\"\n├── Budget: 50-60% of total\n└── Goal: Qualified leads\n\nCAMPAIGN 3: Research/Consideration\n├── Ad Group: Service + Info\n│   ├── \"best [service]\"\n│   ├── \"[service] comparison\"\n│   └── \"how much does [service] cost\"\n├── Budget: 20-25% of total\n└── Goal: Top-funnel leads\n\nCAMPAIGN 4: Competitor\n├── Ad Group: Competitor Names\n│   ├── [competitor 1]\n│   ├── [competitor 2] alternative\n│   └── Strict negatives\n├── Budget: 5-10% of total\n└── Goal: Competitive conquest\n```\n\n### Ad Group Best Practices\n\n```\nAD GROUP SETUP FOR LEAD GEN\n════════════════════════════\n\nKEYWORDS PER AD GROUP:\n──────────────────────\n□ 10-20 keywords per ad group (STAG approach)\n□ Same intent cluster\n□ Same landing page\n□ Same ad copy theme\n\nMATCH TYPE STRATEGY (Lead Gen 2026):\n───────────────────────────────────\n┌──────────────────────────────────────────────────────────────────────┐\n│ Match Type │ Budget % │ Use Case                                     │\n├────────────┼──────────┼──────────────────────────────────────────────┤\n│ Exact      │ 30-40%   │ Proven converting queries, brand terms       │\n│ Phrase     │ 20-30%   │ Core service terms, medium accounts          │\n│ Broad      │ 30-50%   │ Scale with Smart Bidding — Google's primary  │\n│            │          │ recommendation for accounts >30 conv/month   │\n└────────────┴──────────┴──────────────────────────────────────────────┘\n\nLEAD GEN SPECIFIC:\n├── Broad match REQUIRES tCPA or Max Conversions bidding (never manual)\n├── Heavy negatives for quality regardless of match type\n├── For accounts <30 conversions/month: stick to exact+phrase only\n└── Focus on qualified leads, not CTR\n```\n\n## RSA Best Practices\n\n### Responsive Search Ad Structure\n\n```\nRSA ANATOMY (2025)\n══════════════════\n\nHEADLINES (Max 15, Min 8):\n──────────────────────────\nPosition 1 Headlines (Pin 2-3):\n├── [Keyword] - [Primary Benefit]\n├── [Service] Request | Direct Contact\n└── \"[Keyword]\" + CTA\n\nPosition 2 Headlines (Pin 1-2):\n├── [Key USP]\n├── Free [Quote/Consultation/Demo]\n└── [Social Proof]\n\nPosition 3+ Headlines (No Pin, let Google test):\n├── Benefit statements\n├── Trust signals\n├── Urgency (where appropriate)\n├── Location specific\n└── CTA variations\n\nDESCRIPTIONS (Max 4, Min 3):\n────────────────────────────\nDescription 1 (Pin to position 1):\n├── Keyword + primary value prop\n├── Call-to-action\n└── Max 90 chars for visibility\n\nDescription 2-4 (No pinning):\n├── Social proof / testimonials\n├── Process explanation\n├── Trust signals\n└── Secondary benefits\n\nAD STRENGTH TARGETS:\n────────────────────\n□ \"Excellent\" = no guarantee of better performance\n□ \"Good\" = sufficient, focus on conversions\n□ Minimum \"Average\" = below this level action required\n```\n\n### Improving Ad Strength\n\n```\nAD STRENGTH OPTIMIZATION\n═════════════════════════\n\n\"POOR\" OR \"AVERAGE\" AD STRENGTH? CHECK:\n────────────────────────────────────────\n\n1. HEADLINE DIVERSITY\n   □ Use all 15 headline slots\n   □ Vary sentence structure\n   □ Mix keywords, benefits, CTAs\n   □ Avoid repetition\n\n2. DESCRIPTION DIVERSITY\n   □ Use all 4 description slots\n   □ Each with unique message\n   □ Different lengths\n\n3. KEYWORD INCLUSION\n   □ Keywords in minimum 3 headlines\n   □ Keywords in minimum 1 description\n   □ Natural fit, no keyword stuffing\n\n4. UNIQUE SELLING POINTS\n   □ Minimum 5 unique USPs incorporated\n   □ Concrete numbers (30% discount, 1000+ customers)\n   □ Differentiators vs competitors\n\nQUICKLY IMPROVE AD STRENGTH:\n────────────────────────────\n□ Add \"popular\" headlines that Google suggests\n□ Include prices/numbers\n□ Add location headlines\n□ Mix short and long headlines\n```\n\n\n\n## Ad Extensions Setup\n\n### Required Extensions for Lead Gen\n\n```\nAD EXTENSIONS CHECKLIST (Lead Gen)\n══════════════════════════════════\n\n1. SITELINK EXTENSIONS [REQUIRED]\n─────────────────────────────────\nMinimum 4 sitelinks (max 8 for desktop):\n\nLead Gen Sitelinks:\n├── \"Request a Quote\" → /quote\n├── \"Call Us Directly\" → /contact (with phone number)\n├── \"Our Services\" → /services\n├── \"About Us\" → /about\n├── \"Reviews & References\" → /reviews\n├── \"Free Consultation\" → /consultation\n├── \"FAQ / Common Questions\" → /faq\n└── \"Locations\" → /locations\n\nSitelink Best Practices:\n□ 25+ characters descriptions\n□ Unique landing pages\n□ Mobile-first thinking\n□ Track sitelink conversions\n\n2. CALLOUT EXTENSIONS [REQUIRED]\n────────────────────────────────\nMinimum 4 callouts (max 10):\n\nExamples:\n├── \"Free Quote\"\n├── \"Response Within 24 Hours\"\n├── \"No Call-Out Fee\"\n├── \"Certified\"\n├── \"15+ Years Experience\"\n├── \"Personal Advice\"\n├── \"Custom Solutions\"\n├── \"Flexible Hours\"\n├── \"All-Inclusive Pricing\"\n└── \"Satisfaction Guarantee\"\n\n3. STRUCTURED SNIPPETS [REQUIRED]\n─────────────────────────────────\nChoose relevant headers:\n\nServices: [service 1], [service 2], [service 3]\nTypes: [type 1], [type 2], [type 3]\nBrands: [brand 1], [brand 2], [brand 3] (if dealer)\n\n4. CALL EXTENSIONS [CRITICAL FOR LEAD GEN]\n──────────────────────────────────────────\n□ Main phone number\n□ Call tracking number (via Google Ads or third party)\n□ Schedule: Only show during business hours\n□ Mobile: Click-to-call prominent\n\n5. LEAD FORM EXTENSIONS [OPTIONAL]\n──────────────────────────────────\nNative Google lead forms:\n├── Low friction (no landing page needed)\n├── Pre-filled with Google account data\n├── Directly in search results\n├── CRM integration (Zapier, native)\n\nWARNING: Trade-off: Lower lead quality vs more volume\n```\n\n### Advanced Extension Setup\n\n```\nADVANCED EXTENSIONS\n═══════════════════\n\n6. LOCATION EXTENSIONS\n──────────────────────\n□ Link Google Business Profile\n□ Show distance in ads\n□ Driving directions\n□ Store visits tracking\n\n7. PRICE EXTENSIONS\n───────────────────\nIdeal for services with fixed pricing:\n├── \"Consultation\" - \"From $99\"\n├── \"Basic Package\" - \"$199/month\"\n├── \"Premium Service\" - \"$499\"\n└── Link to relevant pages\n\n8. IMAGE EXTENSIONS\n───────────────────\n□ Relevant product/service image\n□ 1.91:1 aspect ratio\n□ High quality, no text in image\n□ A/B test different images\n\n9. BUSINESS NAME & LOGO\n────────────────────────\n□ Automatically from Business Profile\n□ Ensure correct branding\n□ Logo meets guidelines\n\nEXTENSION SCHEDULING:\n─────────────────────\n□ Call extensions: Business hours only\n□ Sitelinks \"Call Now\": Office hours only\n□ Urgency callouts: Specific days/times\n```\n\n## Lead Form Extensions Setup\n\n### Native Lead Forms Configuration\n\n```\nLEAD FORM EXTENSION SETUP\n══════════════════════════\n\nWHEN TO USE:\n────────────\nYes: Volume more important than quality\nYes: Simple lead capture (name, email, phone)\nYes: No complex qualification needed\nYes: Mobile-heavy traffic\n\nWHEN NOT TO USE:\n────────────────\nNo: Complex B2B with qualification questions\nNo: High-value leads needing nurturing\nNo: When landing page is part of the sales process\n\nSETUP STEPS:\n────────────\n1. Campaign → Extensions → Lead Form\n2. Choose form type:\n   ├── More leads: Shorter form, more volume\n   └── More qualified: Longer form, better quality\n\n3. Configure fields:\n   STANDARD FIELDS:\n   ├── Name (always on)\n   ├── Email (always on)\n   ├── Phone number (optional)\n   └── City/Postal code (optional)\n\n   CUSTOM QUESTIONS (max 5):\n   ├── \"When do you need this service?\"\n   │   └── Options: Immediately, Within 1 month, 1-3 months, Later\n   ├── \"What is your budget?\"\n   │   └── Options: $1k-5k, $5k-10k, $10k+, Unknown\n   └── \"How can we help you?\"\n       └── Open text field\n\n4. Headline & Description:\n   └── \"Get a free quote\" + short value prop\n\n5. Privacy policy URL:\n   └── Required: link to privacy page\n\n6. Submit button text:\n   └── \"Submit\" or \"Request\"\n\n7. Background image:\n   └── Optional, increases engagement\n\nLEAD DELIVERY:\n──────────────\n□ Webhook to CRM (real-time)\n□ Email notification\n□ Download CSV (manual)\n□ Zapier integration\n```\n\n### Improving Lead Form Quality\n\n```\nLEAD FORM QUALITY OPTIMIZATION\n═══════════════════════════════\n\nPROBLEM: Poor lead quality\n\nSOLUTIONS:\n──────────\n\n1. ADD QUALIFICATION QUESTIONS\n   ├── Budget question filters tire-kickers\n   ├── Timing question prioritizes hot leads\n   └── Specific needs question shows serious intent\n\n2. USE LONGER FORM VARIANT\n   └── Google offers \"More qualified\" template\n\n3. COMBINE WITH LANDING PAGE\n   └── Lead form only for mobile\n   └── Desktop to landing page\n\n4. FAST FOLLOW-UP\n   ├── Contact within 5 minutes = 21x higher connect rate\n   ├── Webhook to sales team\n   └── Auto-responder email\n\n5. LEAD SCORING SETUP\n   ├── Score based on answers\n   ├── High-score leads = priority\n   └── Low-score leads = nurturing track\n```\n\n## Call Tracking Setup\n\n### Google Ads Call Tracking\n\n```\nCALL TRACKING IMPLEMENTATION\n═════════════════════════════\n\nOPTION 1: GOOGLE ADS CALL TRACKING (Free)\n──────────────────────────────────────────\nHow it works:\n├── Google replaces your number with a tracking number\n├── Tracks calls as conversions\n└── Limited: only clicks from ads\n\nSetup:\n1. Tools → Conversions → New conversion → Phone calls\n2. Choose: \"Calls from ads using call extensions\"\n3. Set call length threshold (often 60+ sec)\n4. Link to campaigns\n\nOPTION 2: WEBSITE CALL CONVERSIONS\n───────────────────────────────────\nTracks calls from website (after ad click):\n1. Tools → Conversions → \"Calls from website\"\n2. Implement Google forwarding snippet\n3. Dynamic number replacement\n4. Tracked in full customer journey\n\nOPTION 3: THIRD-PARTY CALL TRACKING\n────────────────────────────────────\nTools: CallRail, CallTrackingMetrics, Infinity\nAdvantages:\n├── Call recording\n├── Call scoring/qualification\n├── Multi-channel attribution\n├── CRM integration\n└── Keyword-level tracking\n\nCALL CONVERSION SETTINGS:\n─────────────────────────\n□ Call length: 60+ seconds (lead gen)\n□ Count: One (not every)\n□ Attribution: Data-driven (if sufficient data)\n□ Value: Average lead value\n```\n\n## Google Ads Script: Lead Gen Campaign Checker\n\n```javascript\n/**\n * Lead Gen Campaign Health Check Script\n *\n * Checks:\n * - Extension coverage\n * - Ad strength\n * - Conversion tracking\n * - Budget utilization\n *\n * Setup:\n * 1. Update CONFIG\n * 2. Schedule: Weekly\n */\n\nvar CONFIG = {\n  EMAIL: 'you@example.com',\n\n  // Thresholds\n  MIN_SITELINKS: 4,\n  MIN_CALLOUTS: 4,\n  MIN_AD_STRENGTH: 'GOOD', // POOR, AVERAGE, GOOD, EXCELLENT\n  MIN_CONVERSION_RATE: 0.02, // 2%\n\n  // Date range\n  DATE_RANGE: 'LAST_30_DAYS'\n};\n\nfunction main() {\n  var report = {\n    campaigns: [],\n    issues: [],\n    recommendations: []\n  };\n\n  var campaigns = AdsApp.campaigns()\n    .withCondition('Status = ENABLED')\n    .withCondition('CampaignType = SEARCH')\n    .get();\n\n  while (campaigns.hasNext()) {\n    var campaign = campaigns.next();\n    var campaignReport = analyzeCampaign(campaign);\n    report.campaigns.push(campaignReport);\n\n    if (campaignReport.issues.length > 0) {\n      report.issues = report.issues.concat(campaignReport.issues);\n    }\n  }\n\n  // Generate recommendations\n  report.recommendations = generateRecommendations(report);\n\n  if (report.issues.length > 0) {\n    sendReport(report);\n  }\n\n  Logger.log('Lead Gen Check Complete');\n  Logger.log('Campaigns analyzed: ' + report.campaigns.length);\n  Logger.log('Issues found: ' + report.issues.length);\n}\n\nfunction analyzeCampaign(campaign) {\n  var name = campaign.getName();\n  var issues = [];\n\n  // Check Extensions\n  var sitelinks = campaign.extensions().sitelinks().get();\n  var sitelinkCount = 0;\n  while (sitelinks.hasNext()) { sitelinks.next(); sitelinkCount++; }\n\n  if (sitelinkCount < CONFIG.MIN_SITELINKS) {\n    issues.push({\n      campaign: name,\n      type: 'EXTENSION',\n      issue: 'Fewer than ' + CONFIG.MIN_SITELINKS + ' sitelinks (' + sitelinkCount + ')'\n    });\n  }\n\n  var callouts = campaign.extensions().callouts().get();\n  var calloutCount = 0;\n  while (callouts.hasNext()) { callouts.next(); calloutCount++; }\n\n  if (calloutCount < CONFIG.MIN_CALLOUTS) {\n    issues.push({\n      campaign: name,\n      type: 'EXTENSION',\n      issue: 'Fewer than ' + CONFIG.MIN_CALLOUTS + ' callouts (' + calloutCount + ')'\n    });\n  }\n\n  // Check Call Extensions\n  var hasCallExtension = false;\n  try {\n    var callExtensions = campaign.extensions().phoneNumbers().get();\n    if (callExtensions.hasNext()) {\n      hasCallExtension = true;\n    }\n  } catch (e) {}\n\n  if (!hasCallExtension) {\n    issues.push({\n      campaign: name,\n      type: 'EXTENSION',\n      issue: 'No call extension active'\n    });\n  }\n\n  // Check Ad Strength per Ad Group\n  var adGroups = campaign.adGroups()\n    .withCondition('Status = ENABLED')\n    .get();\n\n  while (adGroups.hasNext()) {\n    var adGroup = adGroups.next();\n    var ads = adGroup.ads()\n      .withCondition('Type = RESPONSIVE_SEARCH_AD')\n      .withCondition('Status = ENABLED')\n      .get();\n\n    while (ads.hasNext()) {\n      var ad = ads.next();\n      var rsa = ad.asType().responsiveSearchAd();\n      var strength = rsa.getAdStrength();\n\n      if (isWeakAdStrength(strength)) {\n        issues.push({\n          campaign: name,\n          adGroup: adGroup.getName(),\n          type: 'AD_STRENGTH',\n          issue: 'RSA ad strength is ' + strength\n        });\n      }\n    }\n  }\n\n  // Check Conversion Rate\n  var stats = campaign.getStatsFor(CONFIG.DATE_RANGE);\n  var clicks = stats.getClicks();\n  var conversions = stats.getConversions();\n\n  if (clicks > 100) {\n    var convRate = conversions / clicks;\n    if (convRate < CONFIG.MIN_CONVERSION_RATE) {\n      issues.push({\n        campaign: name,\n        type: 'PERFORMANCE',\n        issue: 'Conversion rate ' + (convRate * 100).toFixed(2) +\n               '% is below target ' + (CONFIG.MIN_CONVERSION_RATE * 100) + '%'\n      });\n    }\n  }\n\n  return {\n    name: name,\n    sitelinks: sitelinkCount,\n    callouts: calloutCount,\n    hasCallExtension: hasCallExtension,\n    conversions: conversions,\n    clicks: clicks,\n    issues: issues\n  };\n}\n\nfunction isWeakAdStrength(strength) {\n  var strengthOrder = ['POOR', 'AVERAGE', 'GOOD', 'EXCELLENT'];\n  var minIndex = strengthOrder.indexOf(CONFIG.MIN_AD_STRENGTH);\n  var currentIndex = strengthOrder.indexOf(strength);\n  return currentIndex < minIndex;\n}\n\nfunction generateRecommendations(report) {\n  var recommendations = [];\n\n  var extensionIssues = report.issues.filter(function(i) {\n    return i.type === 'EXTENSION';\n  });\n\n  if (extensionIssues.length > 0) {\n    recommendations.push({\n      priority: 'HIGH',\n      action: 'Add missing extensions for better CTR and lead volume',\n      campaigns: extensionIssues.length + ' campaigns affected'\n    });\n  }\n\n  var adStrengthIssues = report.issues.filter(function(i) {\n    return i.type === 'AD_STRENGTH';\n  });\n\n  if (adStrengthIssues.length > 0) {\n    recommendations.push({\n      priority: 'MEDIUM',\n      action: 'Improve ad strength by adding more headline/description variation',\n      campaigns: adStrengthIssues.length + ' ad groups affected'\n    });\n  }\n\n  return recommendations;\n}\n\nfunction sendReport(report) {\n  var subject = 'Lead Gen Campaign Check - ' + AdsApp.currentAccount().getName();\n  var body = 'Lead Generation Campaign Health Check\\n';\n  body += '=====================================\\n\\n';\n\n  body += 'CAMPAIGNS ANALYZED: ' + report.campaigns.length + '\\n';\n  body += 'ISSUES FOUND: ' + report.issues.length + '\\n\\n';\n\n  if (report.issues.length > 0) {\n    body += 'ISSUES:\\n';\n    body += '───────\\n';\n\n    for (var i = 0; i < report.issues.length; i++) {\n      var issue = report.issues[i];\n      body += '• ' + issue.campaign;\n      if (issue.adGroup) body += ' / ' + issue.adGroup;\n      body += '\\n  ' + issue.issue + '\\n\\n';\n    }\n  }\n\n  if (report.recommendations.length > 0) {\n    body += 'RECOMMENDATIONS:\\n';\n    body += '────────────────\\n';\n\n    for (var j = 0; j < report.recommendations.length; j++) {\n      var rec = report.recommendations[j];\n      body += '[' + rec.priority + '] ' + rec.action + '\\n';\n      body += '  ' + rec.campaigns + '\\n\\n';\n    }\n  }\n\n  body += '\\n---\\nGenerated by Lead Gen Campaign Checker Script';\n\n  MailApp.sendEmail(CONFIG.EMAIL, subject, body);\n  Logger.log('Report sent to ' + CONFIG.EMAIL);\n}\n```\n\n## Output: Search Campaign Setup Template\n\n```markdown\n# Search Campaign Setup Plan\n\n## Campaign Overview\n- **Business type:** [B2B/B2C/Local Service]\n- **Target locations:** [Locations]\n- **Monthly budget:** $[X]\n- **Target CPL:** $[X]\n- **Primary conversion:** [Form/Call/Lead Form]\n\n## Campaign Structure\n\n### Campaign 1: [Name]\n**Type:** Search\n**Bidding:** Target CPA / Maximize Conversions\n**Daily budget:** $[X]\n\n**Ad Groups:**\n| Ad Group | Keywords (sample) | Match Types |\n|----------|-------------------|-------------|\n| [AG1] | [kw1], [kw2] | Exact, Phrase |\n| [AG2] | [kw1], [kw2] | Phrase, Broad |\n\n## RSA Setup\n\n### Headlines (15):\n1. [Keyword-focused headline - PIN position 1]\n2. [Second keyword variation - PIN position 1]\n3. [Primary benefit - PIN position 2]\n4. [Social proof]\n5-15. [Variations on benefits, CTAs, USPs]\n\n### Descriptions (4):\n1. [Keyword + value prop + CTA - PIN position 1]\n2. [Trust + process]\n3. [USPs + social proof]\n4. [Urgency + secondary CTA]\n\n## Extensions Checklist\n- [ ] 6+ Sitelinks configured\n- [ ] 6+ Callouts added\n- [ ] Structured Snippets (2 types)\n- [ ] Call Extension active\n- [ ] Location Extension linked\n- [ ] Lead Form Extension (optional)\n- [ ] Image Extensions added\n\n## Conversion Tracking\n- [ ] Form submission tracking\n- [ ] Call tracking enabled (60+ sec)\n- [ ] Lead form webhook configured\n- [ ] Value per conversion set\n\n## Launch Checklist\n- [ ] All ads reviewed for spelling/accuracy\n- [ ] Landing pages mobile-optimized\n- [ ] Negative keyword lists applied\n- [ ] Budget and bids confirmed\n- [ ] Conversion tracking verified\n```\n\n## Optional: Enrich with Live Data\n\nIf the user has connected their Google Ads account, check for existing campaigns before building new ones to avoid duplication and surface relevant performance history:\n\n```python\n# List active search campaigns with budget, status, and recent performance\ngoogle_ads_run_gaql(\n    customer_id=\"YOUR_CUSTOMER_ID\",\n    query=\"SELECT campaign.name, campaign.status, campaign.advertising_channel_type, campaign_budget.amount_micros, metrics.impressions, metrics.clicks, metrics.conversions, metrics.cost_micros FROM campaign WHERE campaign.advertising_channel_type = 'SEARCH' AND campaign.status != 'REMOVED' AND segments.date DURING LAST_30_DAYS ORDER BY metrics.cost_micros DESC LIMIT 20\"\n)\n```\n\nUse this to understand the existing campaign structure, identify budget already allocated to search, and avoid duplicating keyword coverage. Existing high-performing campaigns may only need RSA copy improvements rather than a full rebuild.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}