Four platforms publish a public archive of the ads running on them: Meta, Google, LinkedIn, and TikTok. None of them require an ad account to read. All of them are awkward to read at scale: different URL structures, different filter vocabularies, different ideas of what an "advertiser" is, and no bulk export.
This guide covers all four through Social Fetch's /v1/**/ad-library/** routes: what each library exposes, the resolve-then-fetch pattern that most integrations get wrong, and how to turn the four into one competitor-tracking pipeline.
You'll need an API key and curl or the TypeScript SDK. New to the API? Start with the Quickstart.
Why four ad libraries exist
They are compliance artifacts, not developer products.
The EU Digital Services Act obliges very large platforms to keep a public repository of the ads they serve. Political-advertising rules in the US, EU, UK, Canada, and elsewhere add stricter disclosure (funder, spend, reach) for election and issue ads. Each platform shipped the minimum viable public interface that satisfies its obligations.
That origin explains almost every rough edge you will hit:
Coverage is uneven. Political ads get spend and impression ranges; commercial ads often get neither. Retention is uneven too, with political archives running for years while commercial creatives frequently disappear once they stop running.
The interface is the product. These are search pages built for journalists and regulators, not endpoints built for pipelines, and there is no "download all ads for this brand" button anywhere.
Nothing is normalized across them. Meta calls it a page, Google calls it an advertiser, LinkedIn calls it a company, and TikTok calls it an advertiser but splits results across two different surfaces.
The data is genuinely public and genuinely useful. Getting it into a table is the work.
What each library actually exposes
| Meta | TikTok | |||
|---|---|---|---|---|
| Surfaces covered | Facebook, Instagram, Messenger, Audience Network | Search, YouTube, Shopping, Maps, Play | LinkedIn feed and message ads | TikTok |
| Free-text keyword search | Yes (required) | No, advertiser or domain only | Yes (keyword) | Yes (Top Ads only) |
| Impressions disclosed | Political and issue ads only | No | Yes: banded, plus per-country share | Relative metrics only |
| Spend disclosed | Political and issue ads only | No | No | No |
| Targeting disclosed | Political and issue ads only | No | Often: language, included and excluded locations | No |
| Creative media | Image, video, meme | Text, image, video | Image, video, carousel, document | Video |
| Date filtering | startDate / endDate | startDate / endDate | startDate / endDate | period (7/30/180 days) |
| Political-ad filter | adType=political-and-issue | topic=political (needs region) | None | None |
The practical read: LinkedIn is the richest for B2B competitive work, because it is the only one that routinely hands you an impressions band and a country-level split on ordinary commercial ads. Meta is the broadest for consumer brands. Google is the only one that tells you which Google surface an ad ran on. TikTok is the only one that ranks creatives by performance.
Resolve the advertiser before you fetch ads
This is the step that breaks naive integrations, and it is worth doing once properly.
Every one of these libraries matches company names by fuzzy substring, not by entity. Search a brand and you get everything containing that string. Here is a real Google Ads Transparency advertiser search:
Ten advertisers, one of which is the company you meant. Notion Labs, Inc with adsEstimate: 200 is the real one; Hit Notion, LLC with 93 ads is a different business entirely. A pipeline that searches by name on every run will silently blend them.
Resolve once, then query by id
Run the name search a single time, have a human confirm the match, and store the stable id: advertiserId on Google, pageId on Meta, companyId on LinkedIn. Every subsequent call should use the id. Name-based lookups are for discovery, not for scheduled jobs.
The same trap exists on LinkedIn. Searching company=Notion returns ads from both Notion (company 30898036) and an unrelated agency called Epic Notion (company 2076480). The advertiser.pageUrl field on each ad carries the company id, so you can resolve it from a first search and pin it thereafter.
Google's response also hands you a websites array. When two advertisers share a name, the domain is usually the fastest disambiguator: notion.so belongs to the company you want, epicnotion.com does not.
Meta (Facebook and Instagram) Ad Library
Meta's library covers Facebook, Instagram, Messenger, and Audience Network. Keyword search is the primary entry point and query is required.
Useful parameters:
searchType:keyword-unordered(default behaviour, words in any order) orexact-phrase. Useexact-phrasewhen you are tracking a specific claim or slogan.adType:all, orpolitical-and-issueto restrict to the disclosure-heavy subset that carries spend and impression ranges.status:active,inactive, orall. Active-only is what you want for "what are they running right now".mediaType:image,video,meme,image-and-meme, ornone.country: a country code, orALLto search every country at once.trim: returns a smaller payload with fewer fields.
To follow one brand rather than a keyword, resolve the page first and then list its ads:
Single-ad detail lives at GET /v1/facebook/ad-library/ads by adId or public url. It accepts includeTranscript=true, which returns plain text for video creatives, useful when you want to analyse messaging rather than eyeball thumbnails.
Meta's own API is narrower than it looks
Meta publishes an official Ad Library API, but it needs an approved app, and identity verification for political ads. For non-political ads its search is largely limited to the EU. The public library pages themselves are worldwide. That gap is why most teams read the public surface instead.
Google Ads Transparency Center
Google has no free-text creative search. You cannot ask "which ads mention pricing"; you can only ask "what is this advertiser running". So resolution is mandatory, not optional.
The platform filter is what makes Google worth pulling. It splits an advertiser's spend across google_search, youtube, google_shopping, google_maps, and google_play. Running the same query five times, once per surface, gives you a rough channel-mix picture that no other library offers: whether a competitor is a search-first advertiser who dabbles in YouTube, or the reverse.
format narrows to text, image, or video. topic=political restricts to election and issue ads, and requires region to be set.
Single creatives resolve by their public Ad Transparency URL at GET /v1/google/ad-library/ads.
LinkedIn Ad Library
For B2B competitive research this is the highest-value library of the four, because LinkedIn discloses reach and targeting on ordinary commercial ads.
Search by company name, companyId (preferred, see above), or keyword for free-text across ad copy. countries takes a comma-separated list. A trimmed real response:
Three fields there are hard to get anywhere else:
impressions.total: a banded reach figure (20k-30k,50k-100k) on a normal commercial ad.impressions.byCountry: where those impressions actually landed, as percentage shares. The ad above is nominally targeted at several regions but 85% of delivery is Spanish-speaking Latin America and Spain. That is a market-priority signal you will not find in a press release.targeting: the advertiser's own selections, sometimes including exclusions.
adType is also worth storing: Single Image Ad, Video Ad, Carousel Ad, Document Ad, and Message Ad are meaningfully different plays. A jump in Document Ads usually means a new gated asset and a lead-gen push.
Note that impressions and duration are populated on some ads and null on others. LinkedIn only discloses them once an ad has finished or crossed a reporting threshold. Branch on null rather than assuming presence.
TikTok — Top Ads vs the Ads Library
TikTok is the one that surprises people, because GET /v1/tiktok/ad-library/ads/search fronts two different data sources depending on which parameter you set.
Set advertiserName and you query the public Ads Library: the compliance surface, comparable to the other three:
Omit it and you query Top Ads: TikTok's curated collection of high-performing creatives, which is a creative-research tool rather than a transparency archive:
Top Ads filters have no equivalent on the other platforms:
orderBy:ctr,cvr,impression,like,play-2s-rate,play-6s-rate, orfor-you. Sorting byplay-6s-ratesurfaces creatives that hold attention past the scroll-away point.industry: 21 verticals frombeauty-personal-caretofinancial-services.objective:conversions,lead-generation,app-installs,traffic,reach,product-sales,video-views.adFormat:spark-ads(boosted from an organic post) versusnon-spark-ads(uploaded as pure ad creative). The ratio tells you whether a category leans on creator partnerships.duration,likes,adLanguage,period(7, 30, or 180 days).
Use Top Ads to answer "what creative patterns work in this vertical right now". Use advertiserName to answer "what is this specific company running". They are not interchangeable, and mixing them in one table will produce nonsense.
Building competitor ad tracking
The four libraries share an envelope, so one worker handles all of them. The shape that works:
Four rules that matter more than the fetching code:
Dedupe on the platform ad id, never on the creative. The same creative is republished under new ids constantly: the LinkedIn response above contains four separate ids for one "AI Can't Replace Teamwork" video, each a different delivery variant. Counting creatives instead of ids will make a single campaign look like a blitz.
Store first_seen and last_seen yourself. Retention is a rolling window on every platform. An ad that vanishes from the library has stopped running, but you only know that if you recorded it while it was there. This is the single highest-value thing your pipeline does, because it turns four ephemeral search pages into a real time series.
Snapshot, do not overwrite. impressions.total moves as an ad accumulates delivery. Append rows rather than updating in place, or you lose the growth curve.
Fan out, then merge. Run the four platforms in parallel and normalize into one row shape: platform, ad_id, advertiser_id, ad_type, body_text, media_url, started_at, ended_at, impressions_band, first_seen, last_seen. The per-platform extras go in a JSON column.
For scheduled runs, monitors and webhooks will push changes to you instead of you polling on a cron.
The weekly report this makes possible
Weekly, per competitor: new creatives launched, creatives retired, share of Document or lead-gen formats, and country mix shift from LinkedIn's byCountry split. That last one is often the earliest public signal that a competitor is opening a new market, usually weeks before an announcement.
What ad libraries will not tell you
Being straight about the ceiling here saves you from over-promising internally.
- No spend, outside political ads. Meta discloses spend ranges for political and issue advertising. For everything else, nobody publishes budget. Anyone selling you competitor ad spend is modelling an estimate, not reading a number.
- No conversions, and no funnel. You see creative and, on LinkedIn, banded reach. Whether it worked is invisible.
- No guaranteed completeness. Libraries omit ads under review, some formats, and some regions. Absence is not proof an advertiser is dark.
- Impressions are bands, not counts.
50k-100kis the disclosure. Do not average the band and present it as a figure. - Targeting text is prose, not structure. LinkedIn's
targeting.locationis a human-readable string with truncation ("and 3 others"). Parse it defensively. - Ads disappear. Retention differs by platform and ad type. Your own store is the archive.
None of that undercuts the use case. Creative, cadence, format mix, market focus, and messaging shifts are all readable, and all genuinely hard for a competitor to hide.
FAQ
Do I need an ad account to use an ad library API?
No. All four libraries are public transparency surfaces, published because of regulation such as the EU Digital Services Act and various political-advertising rules. You are reading disclosure pages any logged-out visitor can open, not your own campaign reporting. You never touch Meta Ads Manager, Google Ads, or LinkedIn Campaign Manager.
Is this the same as Meta's official Ad Library API?
Meta's own Ad Library API requires an approved developer app and, for political and issue ads, identity verification, and it limits most non-political ad search to the EU. Social Fetch reads the same public library pages and returns them as JSON under /v1/facebook/ad-library/**, with no app review. The underlying data is Meta's; the access path is different.
Which ad library gives the most useful targeting data?
LinkedIn. Its detail pages disclose an impressions band (for example 50k-100k) plus a per-country impression share breakdown, and often the targeting the advertiser selected: language, locations included and excluded. Meta discloses impressions and spend ranges mainly for political and issue ads. Google gives you format, surface, and date range but no impression counts.
Can I search all four ad libraries with one query?
Not in a single request: each platform has its own route and its own filter vocabulary. What is shared is the auth header, the data + meta envelope, and cursor pagination, so one client and one set of response-handling code covers all four. Fan out four calls in parallel and merge on your side.
How far back does ad library data go?
It varies by platform and ad type, and none of them promise a complete archive. Meta keeps political and issue ads for seven years and commercial ads only while they are active or recently inactive. Google and LinkedIn expose roughly the last year for most commercial creatives. Treat every library as a rolling window. If you need history, store what you pull.
Why does searching a brand name return other companies?
Because name search is fuzzy substring matching, not entity resolution. Searching Notion in Google Ads Transparency returns Notion Labs, Inc alongside Epic Notion, Quiet Notion, and Hit Notion, LLC. Always resolve to a stable id (advertiserId, pageId, or companyId) once, store it, then query by id afterwards. See Resolve the advertiser before you fetch ads.
How are ad library lookups billed?
Per completed lookup, like every other route. Read meta.creditsCharged on each response rather than assuming a fixed number, and reconcile against it in your pipeline. Search routes that return a page of results are metered separately from single-ad detail fetches. Check the operation page before you wire a loop.
Is collecting ad library data legal?
These are public transparency archives that platforms are required to publish, which puts them on firmer ground than most public-web collection. You remain responsible for each platform's terms, applicable privacy law, and your own contracts. Ad creatives are copyrighted works, so republishing them is a different question from analysing them. This is a technical guide, not legal advice.
How does this compare to other providers?
See the side-by-side comparisons: vs Apify, vs Bright Data, vs ScrapeCreators, and the full compare hub.
Next steps: Facebook ad search · Google advertiser search · LinkedIn ad search · TikTok ad search · Quickstart · Pricing