The moment I started trusting AI to write ad copy, I immediately stopped trusting AI to write ad copy.

Here’s what happened. I asked Claude to refresh the headlines on a property management account. It produced 15 headlines that looked great — proper character counts, good variety, natural CTAs. I was about to push them to the sheet when I noticed one: “Enjoy Our Rooftop Pool.”

The property doesn’t have a rooftop pool. It has a ground-level pool. The rooftop has a lounge. Claude had merged two amenities into one that doesn’t exist. And the scary part — it read perfectly. If I’d been moving fast across 15 accounts, I’d have shipped it.

That was the last time I let AI write ad copy without scraping the website first.

Get the RSA Refresh skill → github.com/fourteenwm/ppc-ai-skills/rsa-refresh

Free and open-sourced. Requires Firecrawl API key for website scraping and Google Ads API credentials.

The Problem: LOW Assets Are Expensive and Everywhere

Google’s RSA asset labels — BEST, GOOD, LOW, LEARNING — are imperfect signals, but they’re not nothing. A headline labeled LOW has been tested across enough impressions for Google to determine it’s underperforming relative to the other headlines in that ad.

The standard advice is “replace your LOW assets with better ones.” The problem is that “better” usually means “ask the AI to write something new,” and the AI will happily generate headlines that sound professional but contain claims the business never made.

“Family-Owned Since 1952” for a business that opened in 2019. “Free Estimates” when they charge $89 for diagnostics. “Open Saturdays” when they close at noon on Friday. The AI doesn’t know these things are wrong. It just knows they’re plausible for the industry, and plausible is all it takes to pass a casual review.

The RSA Refresh skill exists to break this cycle. It replaces LOW assets — but only with copy that’s been verified against the actual business website.

How It Works: Three Stages

Stage 1: Prepare the Context

The skill queries the Google Ads API for all existing RSAs in the account, including asset performance labels. Then it scrapes the business website using Firecrawl and extracts every verifiable claim — services offered, amenities, credentials, hours, team qualifications, anything that’s explicitly stated on the site.

Both data sets — current ad performance and website claims — get bundled into a context file. This is the raw material Claude works from. Nothing else.

Stage 2: Generate Replacement Copy

Claude reads the context file and generates replacement headlines and descriptions for every ad that has LOW-rated assets. The rules are strict:

What gets replaced:

  • Headlines rated LOW by Google
  • Descriptions rated LOW

What gets preserved:

  • Assets rated BEST or GOOD (never touch what’s working)
  • The ad customizer headline (slot 1, dynamic insertion)
  • Final URLs, paths, and ad structure

What the AI can use as source material:

  • Explicit claims found on the business website
  • Nothing else

This is where the Ad Copy Verification Standard does its work. Every headline Claude generates has to trace back to something on the website. If the website doesn’t mention a rooftop pool, the headline doesn’t mention a rooftop pool. If the website doesn’t list Saturday hours, the headline doesn’t claim Saturday hours.

The skill includes a hallucination filter — a defense-in-depth layer that catches common AI fabrication patterns even when the verification step should have caught them first. Proximity claims like “minutes from downtown” (unless the website says exactly that). Superlatives like “best apartments” or “#1 rated.” Pricing language, promotional terms, unverified luxury words. If it shows up in the generated copy and it’s not on the website, it gets flagged before it reaches the sheet.

Stage 3: Write to Sheet

The output goes to a Google Sheet with two tabs:

  • Original RSAs — the current state with performance ratings, so you can see exactly what’s being replaced and why
  • Refreshed RSAs — the new version in Google Ads Editor import format, ready to upload

The two-tab format exists for review. I don’t auto-push refreshed RSAs to the API. I read the Refreshed tab, compare it to the Original tab, and import through Editor when I’m satisfied. The skill handles the generation. The human handles the approval. Same philosophy as Mutation Safety.

The Headline Structure

The skill generates 15 headlines per RSA following a specific distribution:

TypeCountWhat It Is
Keyword-driven2Match the ad group’s theme (bedroom count, geography, brand)
Standard CTA2”Schedule A Tour,” “Call Us Now”
Outcome CTA1Action tied to the business category
Unit/Product type1What’s available (floor plans, service types)
Brand1Business name
Feature4Verified amenities with action verbs (“Swim In Our Courtyard Pool”)
Benefit3Lifestyle outcomes tied to verified features

The distribution matters because Google serves random subsets of your 15 headlines together. If all 15 are CTAs, some combinations will read like a desperate sales pitch. If all 15 are feature-focused, some combinations will lack a clear next step. The structure ensures every possible rotation has a balanced mix.

The Hardest Part: Benefit Headlines

Feature headlines are straightforward — the website says “resort-style pool,” the headline says “Enjoy Our Resort-Style Pool.” The source is obvious.

Benefit headlines are harder because they describe what changes for the customer, not what exists at the business. “Come Home To Your Private Retreat” sounds nice, but it’s exactly the kind of headline AI loves to generate without any grounding.

The skill enforces a feature-forward process for benefits:

  1. Start from a verified feature on the website
  2. Ask: “What changes for the customer because this feature exists?”
  3. Write the headline from that change
  4. Rejection test: “Could this headline apply to ANY business in this category?” If yes, it’s too generic — go back to step 2

This produces headlines like “Two Sinks For Busy Mornings” (grounded in the verified double-sink vanity) instead of “Come Home And Truly Unwind” (grounded in nothing). The first one could only apply to properties with double vanities. The second one could apply to literally any apartment in the country.

If fewer than 3 benefits pass the rejection test, the skill fills the remaining slots with additional feature headlines. Better to have 7 feature headlines and 0 benefits than 4 features and 3 generic benefits that could be for any business.

Empty > Generic. Same principle as the verification standard, applied to a different problem.

What This Looks Like at Scale

I run this across accounts that need RSA refreshes — usually triggered by a monthly performance review that flags accounts with multiple LOW-rated assets. The workflow:

  1. Pull the account’s RSAs and performance labels via the API
  2. Scrape the business website via Firecrawl
  3. Generate replacement copy for LOW assets
  4. Review the Refreshed tab against the Original tab
  5. Import through Google Ads Editor

The generation step takes about 2 minutes per account. The review step takes another 2-3 minutes. For a batch of 10 accounts needing refreshes, the whole cycle is done in under an hour — including review.

Before this skill existed, the same work was either not getting done (too tedious to manually rewrite headlines across dozens of ads) or getting done badly (quick rewrites without checking the website, leading to the hallucination problems that started this whole project).

The Voice Consistency Problem

One thing I didn’t anticipate: when Google serves random subsets of your 15 headlines, tonal mismatches become obvious. If headline 3 is urgent and transactional (“Act Now — Limited Availability!”) and headline 7 is warm and lifestyle-oriented (“Your Peaceful Retreat Awaits”), they’ll occasionally appear together and the ad will read like two different businesses wrote it.

The skill addresses this by requiring all 14 non-customizer headlines to match the business’s natural voice — pulled from their website copy. If the website is warm and inviting, all headlines are warm and inviting. If the website is direct and professional, all headlines are direct and professional.

The litmus test: could any 3 headlines appear side by side without tonal whiplash? If not, something needs to change.

Get the RSA Refresh Skill

Install in 30 seconds

→ View the skill on GitHub

Copy the SKILL.md file into your Claude Code project:

mkdir -p .claude/skills/rsa-refresh
curl -o .claude/skills/rsa-refresh/SKILL.md \
  https://raw.githubusercontent.com/fourteenwm/ppc-ai-skills/main/rsa-refresh/SKILL.md

Requires a Firecrawl API key for website scraping and Google Ads API credentials for pulling RSA performance data. The skill also includes reference docs for headline structure, voice lifting, and the hallucination filter.

Free. Open-sourced. MIT licensed.

The full repo has 32 PPC AI skills I use in production — mutation safety, SQR classification, portfolio health prioritization, and more. All at github.com/fourteenwm/ppc-ai-skills.

The Bigger Point: Generation Without Verification Is a Liability

The AI ad copy conversation right now is almost entirely about speed. How many headlines can you generate per minute. How fast can you refresh an entire account. How much manual copywriting you can eliminate.

Speed without verification is how you end up with “Enjoy Our Rooftop Pool” on a property that doesn’t have one. And the worst part isn’t the mistake itself — it’s that the mistake looks right. It passes review. It goes live. It stays live until a client calls you on it or a prospect shows up expecting a rooftop pool that doesn’t exist.

The RSA Refresh skill is built on the premise that the right speed for ad copy generation is “as fast as you can verify.” Scrape the website. Extract the claims. Generate from verified sources. Filter the hallucinations. Review the output. Then — and only then — push it live.

It’s slower than raw AI generation. It’s faster than doing it by hand. And the copy that comes out the other end is copy you can actually trust, because every claim in every headline traces back to something the business actually said about itself.

Build the verification into the generation. Not after it.