Home › Guides › Facebook Ads Library scraper
Facebook Ads Library scraper: Meta ads as rows, with EU reach, payer and agency
The public Meta Ad Library shows the ads that run on Facebook, Instagram, Messenger, Threads and Audience Network. The Facebook Ads Library Scraper reads it by search term, advertiser or Ad Library link and returns every ad as one row: ad text, headline, images and videos, start date and days running, platforms, call to action, landing page and domain. For ads shown in the EU, the same row carries what Meta publishes under the Digital Services Act — total EU reach, reach by age, gender and country, targeting, payer and beneficiary. No Facebook account, none of your cookies, no browser.
Who it's for
- Competitor research — every ad a brand runs, how long each has been running and on which platforms.
- EU reach analysis — how many people each ad reached in the EU, by age, gender and country, and whom it targeted.
- Agencies — which advertisers pay through an agency (
paidByThirdParty,thirdPartyPayer) and which agency it is. - Lead generation — businesses that advertise on Meta in a niche and country, with the e-mails and phones their own websites publish.
- Monitoring — a scheduled run with
onlyNewAdsdelivers only new ads, and you pay only for those (plus the run-start event). - Research — political and issue ads with spend, impressions and audience.
What you get
| Group | Fields |
|---|---|
| Ad | Ad Library ID and link, active flag, start and end date, days running, platforms, display format (image, video, carousel, DPA, DCO…), number of versions, ad categories |
| Creative | Ad text, headline, link description, display URL, CTA text and type, image and video URLs, carousel and catalog cards |
| Destination | Link URL, landing URL with Facebook redirects unwrapped, landing domain, UTM parameters |
| Advertiser | Page ID, name, URL, categories and likes; Instagram username and followers and page verification (from the EU details, or with the “Advertiser info” option for other ads); with that option, also the legal owner Meta confirmed and its country |
| EU transparency | Total EU reach, reach countries, reach by country × age range × gender, targeted locations, ages and gender, payer, beneficiary, third-party payer flag and name |
| Political & issue ads | Spend and impressions ranges with their numeric bounds, reach estimate, currency, “paid for by”, audience by age, gender and region |
| Options | Text inside image ads (OCR); an isNew flag for the only-new-ads monitor |
A real ad row, trimmed, from a platform run on Zalando's page in Germany on 2026-10-01 with “Advertiser info” on:
{
"adArchiveId": "1462322829072299",
"pageName": "Zalando",
"legalOwnerName": "Zalando SE",
"publisherPlatforms": ["INSTAGRAM"],
"displayFormat": "DCO",
"adText": "Was zieh ich an?",
"ctaText": "Learn more",
"landingDomain": "zalando.de",
"euTotalReach": 121422,
"euReachCountries": ["DE"],
"targetAgeMin": 18,
"targetAgeMax": 54,
"targetGender": "Men",
"payer": "Zalando",
"beneficiary": "Zalando",
"paidByThirdParty": false,
"detailsStatus": "ok"
}
EU transparency: where it exists and how to read it
Meta publishes reach, targeting, payer and beneficiary for ads shown in the EU. In an EU country nearly every ad has them: 998 of 1,000 German ads in one measured run. Outside the EU, only ads that were also shown in the EU carry them — 1 of 35 Nike ads in a US search. The detailsStatus field tells you what the transparency fields hold:
ok— the data Meta publishes for the ad;not-in-eu— Meta did not mark the ad for EU transparency, usually because it was not shown in the EU;no-eu-data— an EU ad that came without the data;no-audience-data— a political ad with no audience split yet;failedornot-requested— the details request failed, or EU transparency was switched off.
One trap worth knowing: Meta's age and gender buckets do not add up to the total reach. In 649 of 998 measured ads the buckets summed to more than the total EU reach. The scraper returns the buckets exactly as Meta publishes them and computes no per-country totals of its own.
Spotting agencies with paidByThirdParty
In the EU disclosure, an ad's payer can be a different organisation from its beneficiary — usually an agency. paidByThirdParty flags those ads and thirdPartyPayer names the payer. In 1,000 German dental ads, 53 of the 980 ads with a disclosed payer named a different payer; most were marketing agencies and practice-marketing firms, and a few were related companies. Read across a search, the two fields answer which advertisers already pay through an agency, and which agency it is.
Advertiser leads: e-mails and phones from their own websites
Switch on includeAdvertiserContacts and each advertiser also gets one row with website, emails, phones, contactPageUrl, its ad count and date range, landing domains and a contactStatus of found, none-found, unreachable or no-website.
- Website — taken from the advertiser's ads: landing pages, display URLs and catalog links. Social networks, app stores, hosted funnel, form and booking pages and click trackers are skipped.
- Pages read — the home page, then the legal notice (Impressum in German-speaking countries) or the contact page.
- Filtering — addresses of chambers, supervisory, government and data-protection offices, outside data-protection officers and role mailboxes such as data protection, press and compliance are dropped.
Measured on 300 “zahnarzt” (dentist) ads in Germany from 176 advertisers: website 79.5%, e-mail 57.4%, phone 56.3%, e-mail or phone 63.1%. The 36 advertisers without a website had ads that lead only to Facebook, Instagram, WhatsApp or an app store (24), had no link (7), or led to a hosted page with no link to an own site (5).
Input examples
A competitor's ads in Germany with EU reach, targeting and the legal owner (Zalando's page ID):
{
"advertisers": ["365604620536"],
"country": "DE",
"maxAdsPerQuery": 100,
"includeAdvertiserInfo": true
}
Dentists advertising in Germany, with one contact row per advertiser:
{
"searchQueries": ["zahnarzt"],
"country": "DE",
"maxAdsPerQuery": 300,
"includeAdvertiserContacts": true
}
Advertisers can be given as a Facebook page ID, a page link or a name; the numeric page ID always works. You can also paste Ad Library links — a search with its filters, an advertiser's page of ads, or a single ad — and the link's own filters win. Other filters cover country, active status, ad type (including political and issue ads), media type, platforms, languages, a date window and sort order. maxAdsPerQuery goes up to 10,000.
Monitoring: only new ads
For scheduled runs, set onlyNewAds and a monitorName. Each search then delivers only ads that the same search — same term, advertiser or link, same filters — did not deliver in earlier runs. Known ads are skipped and not charged, and a changed filter starts a new list. When nothing is new, the run leaves one free status row that says so.
Measured data quality
Platform runs on Apify, 2026-10-01, default memory (512 MB):
| Input | Result | Fill |
|---|---|---|
| “zahnarzt”, Germany, 1,000 ads, defaults | 1,000 ads, all unique | EU reach 99.8% · targeting 98.2% · payer and beneficiary 98% · ad text 99.4% · landing domain 95.7% · image or video 99.8% |
| Same search, 300 ads, advertiser contacts | 300 ads, 176 advertisers | website 79.5% · e-mail 57.4% · phone 56.3% |
| Zalando page, Germany, advertiser info on | 62 ads | ad text, landing domain, image or video, EU reach, payer, Instagram, legal owner: 100% (one large brand) |
| “vote”, US, political and issue ads | 50 ads | spend, impressions, audience by age, gender and region, “paid for by”: 100% |
Spot checks on these runs: 20 random ads, re-opened through their own Ad Library links, matched in all 8 compared fields; 12 of 12 image and video links returned real JPEG, PNG and MP4 files; and a search for ads shown in March 2024 returned 30 ads, all of which ran during that month.
Speed varies with how fast Meta answers: 10 ads took 8–9 s, 100 ads 34 s and 1,000 ads 277–659 s. 300 ads with advertiser contacts took 227–414 s, and text inside images costs about 6 s per picture.
Honest limits
- EU fields are EU-only. Outside the EU, reach, targeting and payer exist only for ads that were also shown in the EU.
- Ranges stay ranges. Spend and impressions of political ads are ranges as Meta shows them; where a bound is open, as in “<100”, the number read from it is null.
- Meta's counts are approximate. Counts above 50,000 show as 50,001 and change between page loads, and the
newestsort is Meta's newest-first order, not a strict date order. - Contacts can belong to an agency when an advertiser sends its ads to an agency's landing page. Sites behind bot protection or very slow ones can stay unreachable.
- A confirmed legal owner is not universal. Large brands usually have one; none of 65 dental practices had one. The option adds one request per advertiser — 100 dentist ads took 70.8 s with it and 33.8 s without — so it is off by default.
- OCR reads pictures, not videos. In a 15-ad test, text was read in 5 of the 8 image ads.
- Personal data. The EU payer or beneficiary of a small business can be a person's name, and contacts are business details the advertiser's website publishes. Use the data in line with the GDPR and your local law. The scraper is independent and not affiliated with Meta.
Pricing
Pay per event: each delivered ad (EU transparency and advertiser info are included in the ad price), each advertiser row whose website gave at least one e-mail or phone, each ad whose picture gave text, plus Apify's run-start event. Status rows and advertiser rows without contacts are free, and each ad is delivered and charged once per run, whichever search finds it first. Current prices are on the actor's Pricing tab.
Related
More ad-intelligence scrapers on foXLabs. TikTok publishes a comparable EU library — see the TikTok Ads Library scraper guide. LinkedIn's own Ad Library is covered in LinkedIn company data without a login, and the wider workflow in firmographics and competitive intelligence.
Frequently asked questions
Do I need a Facebook account or cookies?
No. The scraper reads the public Meta Ad Library without logging in and without your cookies.
Why are the EU fields empty for some ads?
Meta publishes reach, targeting and payer only for ads shown in the EU. In an EU country nearly every ad has them: 998 of 1,000 German ads in one measured run. The detailsStatus value not-in-eu marks the others.
Can I get stopped ads?
Yes, with activeStatus set to inactive or all. A US search for “nike” listed more than 50,000 stopped ads, one of them started in 2023. Meta shows result counts above 50,000 as 50,001.
What does paidByThirdParty mean?
In the EU disclosure, the payer is a different organisation than the beneficiary, usually an agency. thirdPartyPayer gives the payer's name. In 1,000 German dental ads, 53 of the 980 ads with a disclosed payer named a different payer; most were marketing agencies and practice-marketing firms, a few were related companies.
What does a scheduled only-new-ads run return when nothing is new?
One free status row that says so. No ad is charged; only Apify's run-start event applies.
Try it: start with one of the inputs above, or the form's 10-ad default, then pull the rows through the Apify API or into Google Sheets, Make, Zapier or n8n.
Open the Facebook Ads Library Scraper →Or browse all foXLabs datasets on Apify.