← All skills

Research · Competitive

Ad Library Recon

Who a company targets, not who it has already won. Reads live ads out of the LinkedIn, Meta and Google ad libraries with a real browser — they are JavaScript apps that block scrapers outright, so this is the only way in.

Skill name
ad-library-recon
Triggers on
Read a company's live advertising out of the public ad libraries — LinkedIn Ad Library, Meta Ad Library, and Google Ads Transparency Center — using a real browser, because these are JavaScript applications that block scrapers outright. Use this whenever the task needs to know who a company TARGETS rather than who it has already won: building or sharpening an ICP, finding an anti-ICP, checking whether a competitor is moving upmarket, reading a rival's positioning and offer, sizing how seriously someone is spending on a channel, or verifying that a company's stated ICP matches where its money actually goes. Use it when a website read has left the ICP thin, when someone asks "who are they going after", "what ads are they running", "are they targeting enterprise", or "what's their angle" — and specifically when a Firecrawl or Exa attempt on an ad library has already failed, which it will. Prefer this over any scraping approach for ad libraries; they are browser-only.
Read time
7 min · Markdown · free to use and edit
Download .md

Use it in your assistant

Claude Code — drop the file in your skills folder and it loads on the next session. Use ~/.claude/skills for every project, or .claude/skills inside a repo to keep it to that project.

mkdir -p ~/.claude/skills/ad-library-recon
curl -L https://growsteady.io/skills/ad-library-recon/download -o ~/.claude/skills/ad-library-recon/SKILL.md

Claude apps (web and desktop) — Settings → Capabilities → Skills → add a skill. Upload the file as SKILL.md inside a folder named ad-library-recon (zip the folder if an archive is asked for).

No install— paste the file into a Claude Project's custom instructions with “Copy as prompt”. Same behaviour, scoped to that project.

Onboarding — start here

What this does. Pulls a company's live and historical ads out of the three public ad libraries and turns them into ICP evidence: who they target, what offer they lead with, which segment they name, and how much they are spending relative to peers.

Why it exists as its own skill. Every ad library is a JavaScript app behind a search form, and LinkedIn's blocks automated fetching completely — a Firecrawl attempt against linkedin.com/ad-library/search failed on all six engines including stealth proxy. Google's returns a list but serves ad creatives inside tpc.googlesyndication.com iframes that a scraper cannot read. The only route that works is a browser that renders and where the user is already signed in.

What it does not do, and where to go instead.

  • It does not build the whole ICP. It supplies the targeting half. Pair it with icp-research, which covers the website, pricing and client roster.
  • It does not give ad spend in currency. No library publishes that outside political advertising. You get ad counts and date ranges — volume, not budget.
  • It does not work at corpus scale. Budget 3–6 minutes of browser interaction per company. For 40 companies use icp-research and reserve this for the ones still thin afterwards.
  • It is not a competitive-intelligence archive. For historical creative sets at scale, the Google Ads Transparency BigQuery public dataset is the right tool.

Setup. Needs a browser surface: the in-app browser (mcp__Claude_Browser__*) or Claude in Chrome (mcp__claude-in-chrome__*). Prefer Chrome when the user is already logged into LinkedIn — the Ad Library is public but degrades heavily when signed out. Verify with one navigation to https://adstransparency.google.com/?region=NL — if the page renders, you are ready.

Cost. Zero vendor spend. The cost is wall-clock and attention.

How to invoke. "What ads is X running", "check the ad library for X", "are they targeting enterprise", "who does X actually go after".

Boundaries that are not negotiable. These libraries are public records; read them and nothing else. Never sign in on the user's behalf, never enter credentials, never click an advertiser's ad — a click costs a real company real money and pollutes their data. Never accept cookie banners beyond declining non-essential. If a library demands a login the user does not already have, stop and report that rather than creating an account.

Rest of the skill. Per-library mechanics below, then what to extract, then the interpretation rules that stop this producing confident nonsense.


Why targeting data is worth the extra effort

A client roster is revealed preference — who a company won, filtered by survivorship and by what marketing chose to display. Ad targeting is stated preference — who they are spending money to reach right now, declared by them, with budget behind it.

The gap between the two is the finding. An agency whose logo wall is all 20-person startups but whose ads target Director+ at 501-1000 employees is trying to move upmarket and has not landed it. That is invisible from the website, and it changes what "their ICP" means: their aspiration and their reality are different segments, and a study measuring buyer-fit needs to say which one it is scoring against.


LinkedIn Ad Library — the highest value, the most effort

This is the only library that publishes B2B targeting parameters, which is exactly what an ICP needs. It cannot be scraped; drive it in a browser.

Route. https://www.linkedin.com/ad-library/home → search the company name in the advertiser field. Direct URLs of the form /ad-library/search?companyIds=<id> work when you have the numeric company id from the company page URL, which is more reliable than name search for companies with common names.

Mechanics that matter.

  • Search by advertiser, not keyword. Keyword search returns anyone mentioning the term.
  • Results are paginated by infinite scroll. Scroll to load; do not assume the first screen is the full set.
  • Set the date filter deliberately. The default window hides older creative, and the change over time in who they target is more informative than a snapshot.
  • Open an individual ad to reach the detail view. The targeting disclosure lives there, not in the grid, and only for ads served in the EU — the DSA requires it. A company advertising only in North America will show ads with no targeting panel at all, which is a limitation to report, not a null result.

What the targeting panel gives you, and it maps almost directly onto the ICP schema: job function, seniority, company size, industry, location, and sometimes member-interest or list-based audiences. Record it verbatim before interpreting.

Google Ads Transparency Center — fast, shallow, scriptable

The one library where a URL alone gets you something useful.

Route. https://adstransparency.google.com/?region=<CC>&domain=<domain> — for example ?region=NL&domain=coldiq.com. This renders enough that even a plain fetch returns the advertiser's verified legal name, the ad count, and per-creative links. Confirmed working.

Its ceiling. Creatives render inside tpc.googlesyndication.com iframes that a scraper sees as blocked. To read the actual ad copy you need the browser. There is no targeting disclosure here for commercial ads — only political.

Use it as a cheap first pass across many companies to answer: do they advertise at all, under what legal entity, at what volume, since when. That alone separates companies with a real paid motion from those without, and tells you which ones deserve the expensive LinkedIn pass.

Note the region parameter is load-bearing. Ads shown in the EU carry extra disclosure by law. Query the region the company actually sells into, and if in doubt query an EU region as well as the home one.

Meta Ad Library — broad, weak on B2B

Route. https://www.facebook.com/ads/library/ → set country and category All ads, then search the page name. Direct: ?q=<name>&country=<CC>.

Coverage is deep and history is long, but targeting disclosure is limited outside political and issue advertising, and B2B service businesses often do not advertise here at all. Treat an empty result as information — it usually means their buyers are not on Meta, which is itself an ICP signal.


What to extract, per company

Record these, and keep the ad copy verbatim — paraphrasing ad copy destroys the segment language, which is the most useful part.

advertiser_legal_name      # Google gives the registered entity; often differs from the brand
is_advertising             # true / false / not-in-this-region
ad_count, date_range       # volume and recency, not spend
platforms                  # which libraries returned results
targeting_declared         # LinkedIn EU ads only: function, seniority, company size, industry, geo
offer_in_ads               # what they lead with - a demo, a lead magnet, a webinar, a hire
segment_language           # verbatim phrases naming the buyer, e.g. "for RevOps leaders at 200+"
landing_pages              # where ads point; frequently a page the nav does not link

That last field is quietly valuable. Ad landing pages are built for a specific segment and are often unlinked from the main navigation — which means they carry a sharper ICP statement than the homepage, and icp-research can then read them directly.


Interpretation rules

Absence of ads is not absence of a motion. Plenty of strong B2B service businesses run entirely on founder-led content and referral. Record is_advertising: false as a finding about their channel mix, and do not let it lower your ICP confidence — it is evidence about how they sell, not to whom.

Targeting is aspiration; the client roster is outcome. When they disagree, report both rather than reconciling them. The disagreement is more informative than either number, and picking one silently hides the interesting part.

Ad copy segment language beats targeting parameters for wording. The parameters give you machine-readable bands; the copy gives you the words the company uses for its buyer, which is what you actually want when matching against a commenter's self-written headline.

One creative is not a strategy. A company with three ads is testing. A company with twenty running for eight months has a committed segment. Weight your confidence by volume and duration, and say which you saw.

Region gaps are limitations, not nulls. If a company serves North America only, no targeting panel exists anywhere. Report "no EU-served ads, targeting undisclosed" rather than "no targeting" — those read identically in a table and mean completely different things.


Verified behaviour (tested 2026-08-12)

LinkedIn Ad Library renders in a browser without a login. /ad-library/home returned full page text with the search form present and no auth wall — the same URL family that failed on every Firecrawl engine including stealth. The browser-only claim holds, and signed-out access is sufficient to reach the form.

`?companyName=<name>` is NOT a valid search parameter. Navigating to /ad-library/search?companyName=Frontal%20AI returned "Failed to load". Do not guess query parameters. Either drive the form directly, or get the numeric company id from the LinkedIn company page URL and use ?companyIds=<id>.

The pane needs a real viewport. In one session the in-app browser reported Viewport: 0x0; get_page_text still worked but read_page returned an empty accessibility tree, so no element refs existed and the form could not be driven. resize_window did not clear it. When you see a 0x0 viewport, switch to Claude in Chrome rather than retrying — a real Chrome window has a real viewport, and it also carries the user's existing LinkedIn session, which improves results.

Practical order, therefore: try Google Ads Transparency first by URL (cheap, needs no browser at all), and go to Chrome — not the in-app pane — for anything on LinkedIn.