google-ads-copy
Setup
Read and follow ../shared/preamble.md — it handles MCP detection, token, and account selection. If config is already cached, this is instant.
Ad Copy Generator + A/B Tester
Write Google Ads RSA copy and run structured A/B tests to find winning messaging.
Reference Documents
Before generating any copy, read these reference documents for expert-level context:
references/rsa-best-practices.md— Character limits, headline formulas, pinning strategy, A/B methodology, common mistakes- Read from manage skill:
../manage/references/industry-benchmarks.md— Industry-specific CTR benchmarks to beat - Read from manage skill:
../manage/references/quality-score-framework.md— How ad copy impacts Quality Score components
These contain the specific formulas, character counts, and patterns that separate amateur ad copy from expert-level RSAs.
Business Context — Read First, Ask Once
Every ad copy decision depends on understanding the business. Business context is stored in {data_dir}/business-context.json.
On every invocation:
- Read
{data_dir}/business-context.json. If it exists and has content, use it — skip to the next section. - If missing or empty, follow the full intake procedure in
../audit/references/business-context.md(website crawl, data bootstrapping, JSON schema). That document is the single source of truth for gathering business context. - If the user volunteers new info (new service, changed positioning, seasonal update), merge it into the existing file.
How business context shapes copy
| Field | Copy application |
|---|---|
services |
Determines headline categories and description angles |
locations |
Geo-specific headlines get higher quality scores and CTR |
brand_voice |
Tone, forbidden words, preferred language |
differentiators |
These ARE the value prop headlines — the reason someone picks you |
competitors |
Sharpens positioning (without naming them in ads) |
seasonality |
When to push urgency copy vs. evergreen |
social_proof |
Trust signal headlines and descriptions |
offers_or_promotions |
Time-sensitive copy angles, CTA variations |
landing_pages |
Copy must match the page or conversions drop |
Persona-Informed Copy
Cross-reference {data_dir}/personas/{accountId}.json (created by /google-ads-audit) and {data_dir}/business-context.json to ground every piece of copy in real customer data.
How personas shape copy decisions
| Persona Field | Copy Application |
|---|---|
search_terms |
Use these exact words and phrases in headlines — they're the language real customers use |
pain_points |
Lead descriptions with the pain point, then present the solution. Pain > features for click-through |
decision_trigger |
This IS your CTA angle. If the trigger is "seeing reviews mentioned", put the review count in a headline |
primary_goal |
Match H1 to this goal. The first headline should answer "will this page help me do X?" |
demographics |
Adjust register: corporate buyer gets different language than homeowner. Technical user gets specs, consumer gets benefits |
Persona-to-headline mapping
For each ad group, identify which persona(s) it serves:
- Look at the ad group's keywords and match to persona
search_terms - Write H1 using the persona's
primary_goallanguage - Write value prop headlines using the persona's
pain_points(solution framing) - Write CTA using the persona's
decision_trigger
If an ad group serves multiple personas (common in broad campaigns), create separate ad variants — one optimized per persona — and A/B test which performs better.
Ad Strength vs Actual Performance
Google's ad strength score optimizes for Google's internal ad diversity goals, not your conversion rate. Treat it as a secondary signal, never a primary optimization target.
The hierarchy (most to least important)
- Conversion rate — does the ad produce customers?
- CTR — does the ad get clicks from the right people?
- CPA — what does each conversion cost?
- Ad strength — does Google think there's enough variety?
Specific rules
| Situation | Action |
|---|---|
| "Excellent" ad strength, CTR < 2% | Ad strength is misleading. The headlines are varied but not compelling. Rewrite for relevance over diversity |
| "Good" ad strength, CTR > 5% | Do not touch this ad to chase "Excellent". The ad is working. Ad strength is a vanity metric here |
| "Poor" ad strength, CTR > industry avg | Add more headline/description variety to satisfy Google's diversity requirement, but don't change the winning headlines |
| "Poor" ad strength, CTR < industry avg | Both signals agree — the ad needs a rewrite. Start with headline relevance to keywords |
| Ad strength drops after headline edit | If CTR improved, ignore the ad strength drop. If CTR also dropped, revert |
When ad strength IS useful
- Ensuring you have 8+ distinct headlines (not minor variations of the same message)
- Ensuring at least 1 headline per category (service, value prop, trust, CTA)
- Flagging when all descriptions say the same thing in different words
- Catching missing keyword insertion opportunities
Competitive Differentiation
Read {data_dir}/business-context.json competitors and differentiators fields. If empty, infer competitors from auction overlap (high impression share keywords where rank-lost IS is elevated suggest active competitors).
Rules for competitive copy
| Rule | Rationale |
|---|---|
| NEVER name competitors in ad copy | Policy violation risk with Google Ads. Also sends brand awareness to competitors. Even "Better than [Competitor]" is dangerous |
| NEVER use "best" or "#1" without qualification | Google requires substantiation for superlative claims. "Best-Rated on Google" is OK if verifiable. "Best Plumber" is not |
| DO use specific features competitors lack | "Same-Day Service" beats "Better Service". Specificity implies superiority without claiming it |
| DO use pricing advantage if real | "Flat-Rate Pricing" or "From $99" differentiates against competitors with opaque pricing |
| DO use trust signals aggressively | "25+ Years", "4.9★ Google Rating", "500+ 5-Star Reviews" — these are verifiable and powerful |
| DO use location specificity | "Example City's Own [Service]" or "Locally Owned Since 1998" differentiates against national chains |
| DO use speed/convenience | "Same-Day", "24/7", "Book Online in 60 Seconds" — operational advantages competitors may not match |
| DO use guarantees | "Satisfaction Guaranteed", "Free Re-Service", "No Fix, No Fee" — risk reversal converts |
Differentiation angle selection
Based on the competitive landscape, choose the strongest angle:
| Business Situation | Best Differentiation Angle | Example Headline |
|---|---|---|
| Competing against national chains | Local ownership, personal service, community ties | "Family-Owned Since 2005" |
| Competing against cheaper alternatives | Quality, guarantees, reviews, expertise | "Licensed & Insured Pros" |
| Competing against premium alternatives | Value, transparent pricing, same quality for less | "Premium Service, Fair Prices" |
| Unique service offering | The specific feature itself | "Same-Day Emergency Visits" |
| Crowded market, no clear advantage | Speed, convenience, or customer experience | "Book Online — Arrive in 1hr" |
What to pull before writing
Copy should be grounded in what converts, not guesses. One runScript call with ads.gaqlParallel covers everything you need for almost any copy job — fan out the surfaces below in parallel:
- Existing ads (
ad_group_ad) — current headlines, descriptions, ad-strength, per-ad clicks / CTR / conversions. The baseline to beat. - Keywords with quality info (
keyword_view) — what's already converting and which QS components are hurting. - Search terms (
search_term_view) — the actual phrases real customers are typing. The single best source of language for headlines. - Campaign-level CTR / CVR (
campaign) — the benchmark each variant has to beat.
For brand-wide rewrites, correlate everything in one fan-out. For a single ad group, add WHERE ad_group.id = … to each query — the marginal cost is zero. If the user has a database with lead / conversion outcome data, mine it: customer language > marketing language.
Layer on the seasonality and keyword-landscape context from business-context.json. Peak months call for urgency, slow months for evergreen value props. Highly competitive heads need sharper differentiation; long-tail tails need closer intent match.
RSA mechanics
Google RSA: up to 15 headlines (30 chars max) and 4 descriptions (90 chars max). A single character over = rejected. Always count.
The headline formula table (27 formulas across 8 categories) and description formula table (5 formulas) live in references/rsa-best-practices.md — that file is the source of truth for what to actually write.
Pinning strategy:
- Pin 1 Service+Location headline to Position 1 (highest relevance impact)
- Pin 1 CTA headline to Position 3 (Google shows H3 less often — make it count)
- Leave Position 2 unpinned for Google to test value-prop, trust, and differentiator headlines
- Never pin more than 3 total — over-pinning kneecaps Google's optimization
Description ordering:
- D1 = strongest all-around (core value + location). Shows most often.
- D2 = primary differentiator
- D3 = trust / social proof
- D4 = seasonal or offer-based (the slot you swap out when promotions change)
- Every description ends with a CTA verb: Call, Book, Get, Schedule, Request, Visit, Contact
- Punchy at 85 chars beats cramped at 90
A/B testing
When the user wants to test, deploy variants as separate ads in the same ad group (paused, then enabled together). Each variant must test a meaningfully different angle — not word swaps. "Trust & Expertise" vs. "Speed & Convenience" vs. "Price & Value" is a real test; "Call Today" vs. "Call Now" is noise. If the account has multiple personas, create one variant per persona.
Statistical significance thresholds (apply when calling winners):
- <100 clicks per variant → too early to call. Wait.
- 100–200 clicks per variant, <20% relative CTR/CVR difference → functionally equivalent; pick on conversion rate or run a bolder test
- ≥20% relative CTR or CVR delta → real winner
- Either variant with 2× the other's conversion rate → call it immediately, don't wait
Result interpretation matrix:
| CTR | Conv rate | Diagnosis | Action |
|---|---|---|---|
| A higher | A higher | Clear winner | Pause B. Iterate on A's angle with fresh headlines |
| A higher | B higher | A pulls clicks, B converts | Keep B; test A's headlines on B's landing page — message-match may need work. Offer /google-ads-landing |
| Similar | Similar | No meaningful difference | Variants too similar — change the core angle, not the wording |
| Both low | Both low | Neither works | Problem isn't A vs B — keyword intent, landing page, or offer is broken. Suggest /google-ads-audit |
After a winner is called: pause the loser, then create a new variant to test against the winner. Never stop testing.
Operating principles
- Business context is non-negotiable. Read
{data_dir}/business-context.jsonand{data_dir}/personas/{accountId}.jsonfirst. If they don't exist or are stale, recommend/google-ads-auditbefore writing anything generic. - Confirm before deploying. Show the exact copy, character counts per asset, and pin positions. Get a yes, then push.
- Every write returns a
changeId. Tell the user it's undoable within 7 days viaundoChange(assuming the entity hasn't been modified since). - Differentiate, don't imitate. Read the
competitorsfield. Generic copy that could belong to any competitor is a wasted ad slot. - Defer to
/google-adsfor account management. This skill writes copy and deploys RSAs; bid / budget / keyword work belongs in/google-ads.