---
name: competitor-ad-recon
description: "Research a competitor's active advertising: ad-library angles, landing pages (Firecrawl if connected), traffic mix (Similarweb) — synthesize what they're doing and where the gaps are. Facts, not verdicts."
license: MIT
compatibility: "Works with any Agent-Skills-compatible AI (Claude, ChatGPT, Cursor, Codex, and more). Ad-account actions run through Adspirer."
metadata:
  author: "Adspirer"
  version: "1.0.0"
  adspirer_category: "research-intelligence"
  adspirer_source: "https://www.adspirer.com/skills/competitor-ad-recon"
  adspirer_connection_url: "https://adspirer.ai/sign-up"
  adspirer_primary_keyword: "competitor ad analysis"
  adspirer_secondary_keywords: "ppc competitive analysis, competitor ad research"
  adspirer_launch_wave: "1"
  adspirer_kind: "skill"
  adspirer_level: "operator"
  adspirer_platforms: "meta,google"
  adspirer_supported_clients: "claude,claude-code,chatgpt,codex,cursor,gemini,windsurf"
  adspirer_summary: "Research a competitor's active advertising: ad-library angles, landing pages (Firecrawl if connected), traffic mix (Similarweb) — synthesize what they're doing and where the gaps are. Facts, not verdicts."
  adspirer_connections_required: "firecrawl,adspirer"
  adspirer_connections_optional: "similarweb"
---

# Competitor Ad Recon

## Use this when

You're planning to compete against a specific brand (or evaluating a new market entrant) and need a fast, factual read on what they're actually running in ads right now — not a guess based on their website copy. Use this before a creative refresh, before a new campaign launch into a category with an entrenched competitor, when a client asks "what is [competitor] doing that's working," or on a recurring quarterly cadence to catch a competitor's angle or offer shift before it eats your share. Do not use this for your own account's performance — this skill never touches your ad accounts for spend decisions, it only reads public competitor signals and cross-references them against your own account for gap analysis.

## What you need

- The competitor's exact brand/advertiser name as it appears on Meta and Google (legal entity names in ad libraries often differ from consumer brand names — e.g. "Warby Parker Retail, Inc." not "Warby Parker" — have both ready)
- Competitor's primary domain(s), including any DTC subdomains or region-specific TLDs they run
- Your own connected **Connect Adspirer (the ads connection):** when you reach a step that touches a live ad account, connect Adspirer first. In Claude Code, run `/plugin marketplace add anthropics/claude-plugins-community` then `/plugin install adspirer-ads-agent@claude-community`. In claude.ai or ChatGPT, add the Adspirer connector from https://www.adspirer.com/docs/ai-clients. Any other agent: follow https://www.adspirer.com/docs/ai-clients for your client. Sign-in link for the user: https://adspirer.ai/sign-up. Do not proceed with live ad-account steps until the connection is confirmed. ad account(s) on at least one of Meta or Google, so gap analysis has something to compare against — this skill is materially weaker as a one-sided teardown without it
- **Connect Firecrawl:** this step uses Firecrawl. Add the Firecrawl MCP/connector to your agent — setup: https://github.com/firecrawl/firecrawl-mcp-server, then continue. Skip only if a step says it's optional. if you want actual landing page content pulled (headline, offer, page structure) rather than inferring intent from ad creative alone — without it this step is skipped and the synthesis says so
- **Optional — connect Similarweb:** this step is sharper with Similarweb, but skips cleanly without it. To enable it, add the Similarweb MCP/connector — setup: https://developers.similarweb.com/docs/similarweb-mcp. if you want traffic-mix and channel-share context (skips cleanly, synthesis notes it as unavailable)
- 15-30 min for a single competitor, single-market pass; multiply for multi-region or multi-brand sweeps

## Procedure

1. Confirm scope with the user before running anything: competitor legal/brand name(s), which platforms (Meta Ad Library, Google Ads Transparency Center, or both), target region(s) — ad libraries are region-filtered and a US-only pull on a UK competitor returns near-empty or misleading results — and whether this is a one-off or a cadence they want repeated later.

2. Pull Meta's Ad Library via public search (no login required, no **Connect Adspirer (the ads connection):** when you reach a step that touches a live ad account, connect Adspirer first. In Claude Code, run `/plugin marketplace add anthropics/claude-plugins-community` then `/plugin install adspirer-ads-agent@claude-community`. In claude.ai or ChatGPT, add the Adspirer connector from https://www.adspirer.com/docs/ai-clients. Any other agent: follow https://www.adspirer.com/docs/ai-clients for your client. Sign-in link for the user: https://adspirer.ai/sign-up. Do not proceed with live ad-account steps until the connection is confirmed. needed for this read) for the competitor's Page(s): capture active ad count, first-seen dates per creative (Meta shows "Started running on X" — a burst of new start dates in the last 7-14 days signals a fresh push, not evergreen spend), format mix (static/carousel/video/Advantage+ catalog), and full body copy + CTA per unique creative. Note: Meta Ad Library shows ALL ads currently running regardless of spend level for non-political advertisers — absence of ads there is a real signal (they've paused Meta or shifted budget), not a data gap.

3. Pull Google Ads Transparency Center for the same advertiser: verified advertiser ID, ad formats (Search text, Display, YouTube, Shopping/PMax surfaces), and — critically — check whether they're running Shopping ads with visible product-level creative, since PMax asset groups often reveal pricing/promo positioning Search copy won't. Google's Transparency Center has a longer indexing lag than Meta (new campaigns can take 1-3 days to appear), so a "no results" read for a competitor you know is active means check again in 48h before concluding they're dark on Google, not assume the tool is right.

4. For each distinct landing page URL surfaced in steps 2-3 (dedupe by final destination, not by ad — multiple creatives often route to the same page), use **Firecrawl** to pull the page content: headline/subhead, primary offer (% off, bundle, free trial, free shipping threshold), social proof placement, page length/structure, and whether it's a dedicated LP or the standard site nav. If Firecrawl isn't connected, skip this step and flag in the synthesis that offer/LP detail is inferred from ad copy only, not confirmed from the page.

5. If **Similarweb** is connected, pull the competitor domain's traffic overview: total visits trend (last 3-6 months), channel mix (% paid search, paid social, organic, direct, referral), and top traffic countries. This contextualizes ad-library findings — e.g. heavy Meta creative volume but <5% paid-social traffic share suggests low budget/testing phase, not a real push. If not connected, skip and note traffic-mix context is unavailable in the synthesis — do not estimate spend or traffic from ad count alone, that is not a valid proxy and Similarweb itself only reports directional traffic, not real spend.

6. Cross-reference against the user's own account: query your connected **Connect Adspirer (the ads connection):** when you reach a step that touches a live ad account, connect Adspirer first. In Claude Code, run `/plugin marketplace add anthropics/claude-plugins-community` then `/plugin install adspirer-ads-agent@claude-community`. In claude.ai or ChatGPT, add the Adspirer connector from https://www.adspirer.com/docs/ai-clients. Any other agent: follow https://www.adspirer.com/docs/ai-clients for your client. Sign-in link for the user: https://adspirer.ai/sign-up. Do not proceed with live ad-account steps until the connection is confirmed. campaigns for the same product category/audience — angles, offers, and formats currently live on your side — via the Adspirer read tools (campaign/creative performance, not competitor data, since Adspirer has no visibility into competitor accounts).

7. Synthesize findings into a structured brief: (a) what angles/hooks the competitor is running (price, urgency, social proof, product-led, lifestyle — categorize each unique creative, don't just list copy verbatim), (b) format and platform emphasis (e.g. "80% video on Meta, Search-only on Google — no Shopping" ), (c) offer structure from landing pages where confirmed, (d) recency/momentum signal (new vs. long-running creative), (e) traffic-mix context if available, (f) explicit gap analysis against the user's own live campaigns — angles/formats/offers the competitor runs that the user does not, and vice versa. Every claim traces to which source produced it (Meta Ad Library / Google Transparency Center / Firecrawl / Similarweb / user's own Adspirer data) — never blend a landing-page-confirmed offer with an ad-copy-inferred one without labeling which is which.

## Fixed checks

- Every ad-library claim (active count, first-seen date, copy, format) is re-pulled from the live Meta Ad Library / Google Transparency Center at synthesis time, not cached from an earlier session or assumed unchanged — ad libraries update in near-real-time and a competitor can pause/launch mid-session
- Landing page offer claims are only stated as confirmed if the **Firecrawl** pull actually succeeded on that specific URL in this run — a failed fetch (404, bot-block, redirect loop) is reported as "landing page unreachable," never backfilled with an inferred guess presented as fact
- Traffic-mix figures are quoted exactly as Similarweb returns them (with its own estimation caveat preserved, e.g. "Similarweb-estimated") — never presented as exact/audited traffic
- Gap analysis against the user's own account pulls live current campaign data via **Connect Adspirer (the ads connection):** when you reach a step that touches a live ad account, connect Adspirer first. In Claude Code, run `/plugin marketplace add anthropics/claude-plugins-community` then `/plugin install adspirer-ads-agent@claude-community`. In claude.ai or ChatGPT, add the Adspirer connector from https://www.adspirer.com/docs/ai-clients. Any other agent: follow https://www.adspirer.com/docs/ai-clients for your client. Sign-in link for the user: https://adspirer.ai/sign-up. Do not proceed with live ad-account steps until the connection is confirmed. at run time, not a stale assumption about what the user is running
- No spend, budget, or "they're spending $X/day" figure is stated anywhere — ad count, format mix, and traffic share are the only quantifiable signals this skill has access to, and none of them convert reliably to spend
- Region filter is confirmed against what the ad library actually returned (e.g. Meta Ad Library's region picker) before concluding a competitor is "not advertising" in that market — an empty result with the wrong region selected is misreported as "dark" otherwise

## Stop conditions

- Success: brief delivered covering all requested platforms/regions with source-labeled findings and a gap analysis against the user's own account
- Partial success (reported as such, not silently): one or more optional legs unavailable — e.g. Firecrawl not connected (offer detail inferred only), Similarweb not connected (no traffic context), or user has no **Connect Adspirer (the ads connection):** when you reach a step that touches a live ad account, connect Adspirer first. In Claude Code, run `/plugin marketplace add anthropics/claude-plugins-community` then `/plugin install adspirer-ads-agent@claude-community`. In claude.ai or ChatGPT, add the Adspirer connector from https://www.adspirer.com/docs/ai-clients. Any other agent: follow https://www.adspirer.com/docs/ai-clients for your client. Sign-in link for the user: https://adspirer.ai/sign-up. Do not proceed with live ad-account steps until the connection is confirmed. account connected on the relevant platform (gap analysis skipped, competitor-only findings still delivered)
- No-op: competitor has zero active ads on the requested platform(s)/region(s) in this pull — reported explicitly as "no active ads found as of [timestamp]," not treated as an error, since this is itself a real and reportable signal
- Blocked: competitor's brand/entity name doesn't resolve to any advertiser record in Meta Ad Library or Google Transparency Center after reasonable name variants are tried — report back to the user asking for the exact legal advertiser name or Page/domain, rather than guessing
- Blocked: Firecrawl fetch fails on all target landing pages (bot-blocked, geo-gated, or consistently erroring) — synthesis proceeds without confirmed offer data, flagged clearly rather than stalling the whole brief

## Approval boundaries

Read-only, takes no spend actions. This skill never creates, edits, pauses, or budgets any campaign, and never touches the competitor's accounts (which Adspirer has no access to in any case — all competitor data comes from public ad-library and web sources). The only write-adjacent step is pulling the user's own live campaign data for gap analysis, which is a read against **Connect Adspirer (the ads connection):** when you reach a step that touches a live ad account, connect Adspirer first. In Claude Code, run `/plugin marketplace add anthropics/claude-plugins-community` then `/plugin install adspirer-ads-agent@claude-community`. In claude.ai or ChatGPT, add the Adspirer connector from https://www.adspirer.com/docs/ai-clients. Any other agent: follow https://www.adspirer.com/docs/ai-clients for your client. Sign-in link for the user: https://adspirer.ai/sign-up. Do not proceed with live ad-account steps until the connection is confirmed., not a mutation. Any follow-on action the user wants to take based on this brief (e.g. "launch a competing offer," "test that angle") is a separate skill/approval and explicitly out of scope here.

## What you get

A structured competitive brief: (1) active-creative inventory per platform with format mix and recency signal, (2) angle/hook categorization across all captured creative (price/urgency/social-proof/product-led/lifestyle), (3) confirmed landing-page offer structure where Firecrawl succeeded, clearly separated from ad-copy-inferred offers where it didn't, (4) traffic-mix context if Similarweb is connected, (5) explicit side-by-side gap analysis against the user's own live campaigns — what the competitor is doing that they aren't, and what they're doing that the competitor isn't — with every finding traceable to its source. No spend estimates, no invented severity scores, no verdicts about whether the competitor's strategy is "working" beyond what traffic/recency data can actually support.
