Analyze the message match between your ads and landing pages. Checks if the promise in the ad copy carries through to the landing page headline, body, and CTA. Flags disconnects that kill conversion rates. Works with Google, Meta, and LinkedIn ads.
npx gooseworks install --all # then, in Claude Code, Cursor, or Codex: /gooseworks use the ad-to-landing-page-auditor skill
The #1 reason ads get clicks but not conversions: the landing page doesn't deliver on the ad's promise. This skill audits the full click path — from ad copy to landing page experience — and flags every disconnect.
Core principle: A great ad with a mismatched landing page is worse than a mediocre ad with a matched one. Message match is the single biggest conversion lever most startups ignore.
If the user has a CSV export from their ad platform, parse that instead.
Parse the provided ads into:
| Ad ID | Platform | Headline | Body/Description | CTA | Landing Page URL | Conv Rate (if known) |
|---|
For each unique landing page URL, fetch the page content:
fetch_webpage: [landing_page_url]If fetch_webpage is not available, use curl to retrieve the page HTML.
Extract and score:
| Element | Found? | Content |
|---|---|---|
| Hero headline | [Y/N] | "[Text]" |
| Subheadline | [Y/N] | "[Text]" |
| Primary CTA | [Y/N] | "[Button text]" |
| CTA above fold | [Y/N] | — |
| Social proof | [Y/N] | [Logos / testimonials / metrics] |
| Benefit list | [Y/N] | [Key benefits listed] |
| Form / Sign-up | [Y/N] | [Field count: N] |
| Video | [Y/N] | — |
| Trust signals | [Y/N] | [Security badges, guarantees] |
For each ad → landing page pair, score on:
| Dimension | Score (1-10) | Criteria |
|---|---|---|
| Promise continuity | [X] | Does the LP headline deliver on the ad's promise? |
| Language match | [X] | Does the LP use the same words/phrases as the ad? |
| Visual continuity | [X] | Does the LP feel like a continuation of the ad? (Not assessable for search) |
| CTA alignment | [X] | Does the LP's ask match what the ad implied? |
| Specificity match | [X] | If the ad was specific ("for sales teams"), is the LP specific too? |
| Emotional match | [X] | If the ad used fear/urgency, does the LP carry that forward? |
Message Match Score: [Average/60]
| Score | Rating | Meaning |
|---|---|---|
| 50-60 | Excellent | Strong match — LP delivers on every ad promise |
| 40-49 | Good | Minor disconnects but overall coherent |
| 30-39 | Needs work | Noticeable gaps — visitor has to hunt for relevance |
| 20-29 | Poor | Ad and LP feel like different products |
| Below 20 | Critical | Complete mismatch — fix immediately |
Beyond message match, assess landing page conversion friction:
| Friction Type | Check | Status |
|---|---|---|
| Load time | Does the page feel heavy/slow? (Asset count proxy) | [Fast/Slow/Unknown] |
| Form length | How many fields before conversion? | [N fields] — [Appropriate/Too many] |
| CTA clarity | Is there one clear CTA or competing actions? | [Clear/Cluttered] |
| Above-fold conversion | Can someone convert without scrolling? | [Yes/No] |
| Social proof placement | Is proof near the CTA? | [Yes/No] |
| Navigation distraction | Does the LP have full site nav? (Should be minimal) | [Minimal/Full nav] |
| Mobile experience | Any mobile-unfriendly elements? | [Good/Issues] |
# Ad-to-Landing Page Audit — [Product/Client] — [DATE]
Ads audited: [N]
Unique landing pages: [N]
Platform(s): [Google / Meta / LinkedIn]
Overall message match: [Score/60] — [Rating]
---
## Executive Summary
[3-4 sentences: Overall finding, biggest disconnect, top recommendation, estimated conversion impact]
---
## Audit Results by Ad → Landing Page Pair
### Ad 1: "[Ad headline excerpt]"
**Platform:** [Google Search / Meta / LinkedIn]
**Ad copy:**
> Headline: "[text]"
> Body: "[text]"
> CTA: "[text]"
**Landing page:** [URL]
> LP headline: "[text]"
> LP subhead: "[text]"
> LP CTA: "[button text]"
**Message Match Score: [X/60] — [Rating]**
| Dimension | Score | Issue |
|-----------|-------|-------|
| Promise continuity | [X/10] | [Specific finding] |
| Language match | [X/10] | [Specific finding] |
| CTA alignment | [X/10] | [Specific finding] |
| Specificity match | [X/10] | [Specific finding] |
| Emotional match | [X/10] | [Specific finding] |
**Disconnect found:** [Specific description of mismatch]
**Recommended fix:** [Specific change to ad or LP]
### Ad 2: ...
---
## Landing Page Friction Report
### [Landing Page URL]
| Friction Point | Status | Impact | Fix |
|---------------|--------|--------|-----|
| [Friction] | [Red/Yellow/Green] | [High/Med/Low] | [Specific fix] |
---
## Priority Fixes
### Critical (Fix This Week)
1. **[Ad/LP pair]:** [Specific mismatch] → [Specific fix]
- Est. conversion impact: [X% improvement]
### Important (Fix This Month)
2. **[Issue]:** [Fix]
### Nice-to-Have
3. **[Issue]:** [Fix]
---
## Rewrite Suggestions
### For [Ad or LP with worst match]:
**Current ad headline:** "[current]"
**Suggested ad headline:** "[rewrite that matches LP]"
OR
**Current LP headline:** "[current]"
**Suggested LP headline:** "[rewrite that matches ad]"Save to ad-lp-audit-[YYYY-MM-DD].md in the current working directory (or user-specified path).
| Component | Cost |
|---|---|
| Landing page fetching | Free |
| Analysis | Free (LLM reasoning) |
| Total | Free |
Render a 'model comparison grid' video from a config — a fal-style "same prompt, N contenders" showcase — a dark real-DOM stage where per beat a monospace prompt fades in centered, docks to a small top strip, then a labeled 2-4 panel grid (static images OR muted video clips, mixable per cell) staggers in and holds for comparison, plus a minimal end card — frame-stepped via Playwright (video cells are frame-seeked deterministically) and encoded with FFmpeg. Deterministic assembly, FREE (cell media comes from create-image-fal / create-video-fal, music from create-music-elevenlabs), text stays pixel-crisp. Use for the model-comparison-grid format.
Render a punchy ~12s vertical (9:16) music-only direct-response OFFER ad as a 4-beat kinetic-typography film — HEADLINE slam → real PRODUCT drop → CLAIM/proof → CTA pill — from one config of copy slots, a real product photo, a brand palette, fonts, bpm, and beat split. DETERMINISTIC + FREE (a bundled Remotion project; springs + interpolate, no AI-gen for visuals). Backgrounds are engine gradient divs off the palette, props are inline SVG, the ONLY composited bitmap is the REAL product photo (objectFit:contain, never stretched), and ALL headline/claim/CTA/URL/wordmark text is typeset in the engine — never AI-rendered (the format's credibility guard). A driver binds the config to Remotion input props, renders the 9:16 master, and derives a 1:1 center-crop with ffmpeg. Two gating checks run before render (claim verbs must match the product's physical format; the claim beat needs an edge-entry mechanism prop). Use for the motion-graphics-offer-ad format.
Assemble a myth-vs-fact kinetic-typography explainer video ad (≈29.5s, 9:16) from N myth/fact pairs + hook / turn / punch copy + palette + a brand end-card PNG + a VO track — a hook, 3 red-strike MYTH cards that flip to teal-check FACT cards (per-line strikethrough that crosses EVERY wrapped line), a "what actually works" turn, an optional proof reveal, a punch line, and a static end card. DETERMINISTIC assembly with ZERO AI-gen visuals — HTML hyperframes rendered frame-exact via Playwright (`window.renderAt(t)`, animation a pure function of beat-local time), Whisper beat-snap to VO word onsets, concat at a uniform fps, karaoke `.ass` captions burned last (suppressed on the proof + end-card beats), and a VO + optional music mix (music −20 dB, `amix normalize=0`, tail fade). FREE (Python + Playwright + ffmpeg); the recipe supplies the copy / palette / end-card / VO and gates the paid VO / music / Whisper calls to their own capabilities. Use for the myth-vs-fact format.