Facebook Ads Library Scraper: Ad Reach By Region & Age
Pricing
Pay per usage
Facebook Ads Library Scraper: Ad Reach By Region & Age
Extract ad data with the Facebook Ads Library Scraper. Retrieve active and inactive ads, creatives, targeting info, impressions, and engagement metrics. Perfect for competitor analysis, market research, and ad strategy insights. Fast, reliable, and scalable for bulk ad data extraction.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Scrapier
Maintained by CommunityActor stats
0
Bookmarked
30
Total users
4
Monthly active users
3 days ago
Last modified
Categories
Share
Facebook Ads Library Scraper — EU Reach by Age, Country & Gender
Facebook Ads Library Scraper: Ad Reach By Region & Age queries the public Meta Ad Library from a Page URL or an Ad Library search link and returns one row per ad — EU total reach, the age × country × gender reach breakdown, audience targeting, and political spend, impressions, payer and beneficiary data. Every row is structured JSON, ready to feed an LLM, a spreadsheet, or a monitoring pipeline. No Facebook login is required, and the same data structure works for a single advertiser or a whole keyword search.
What is Facebook Ads Library Scraper: Ad Reach By Region & Age?
It is an Apify Actor that reads Facebook Page URLs or Ad Library search links and returns each matching ad's identity, creative, and — where Meta publishes it — its EU audience reach broken down by age, country and gender, plus political-ad payer/beneficiary and spend/impressions ranges. That reach-by-region-and-age breakdown, re-emitted from Facebook's own per-ad transparency payload rather than dropped, is the field competitors in this space typically don't surface. No Facebook account, login, or cookie is required — the Actor authenticates as a guest, the same way any visitor to the Ad Library does.
- Pull ads from one or more Facebook Pages or Ad Library search URLs in a single run
- Filter to political & issue ads only, or keep the full mixed result set
- Toggle a fast advertiser rollup (ad count only) vs. full per-ad detail
- Control country, delivery-status and date-window defaults for Page-based sources
- Get a derived
audienceAnalyticssummary (reach tier, top country, gender/age skew) computed from the raw reach figures - Route through Apify residential proxies when the default guest session gets challenged
What data can you get with Facebook Ads Library Scraper: Ad Reach By Region & Age?
Every run returns ad rows from the dataset's default view, grouped here by what each field covers:
| Result Type | Extracted Fields | Primary Use Case |
|---|---|---|
| Ad identity & status | adArchiveID, pageName, isActive, startDateFormatted, endDateFormatted, inputUrl, scrapedAt | Knowing which ads are live, since when, and where the row came from |
| EU reach & audience breakdown | euTotalReach, ageGenderCountryBreakdown, targeting | Region- and age-level reach intelligence on EU-served ads |
| Derived audience analytics | audienceAnalytics | A ready-made reach tier and demographic skew summary without parsing the raw breakdown |
| Political & issue transparency | isPolitical, payer, beneficiary, spend, impressions | Compliance and political-ad spend/funding monitoring |
EU reach by age, country & gender
This is the block most competing Ad Library scrapers leave out. When includeAudience is on and Meta has published transparency data for an ad, each row carries euTotalReach (total people reached in the EU), ageGenderCountryBreakdown (an array of per-country entries, each broken into age bands with male/female/unknown reach counts) and targeting (the age, gender and location ranges the ad actually reached). This is real, per-ad Meta disclosure data — required under the EU's ad-transparency rules for ads served to EU users — not an estimate. It populates on EU-served ads and is null everywhere else; nothing is interpolated or guessed to fill the gap. A representative shape:
{"euTotalReach": 284000,"ageGenderCountryBreakdown": [{ "country": "DE", "age_gender_breakdowns": [{ "age_range": "25-34", "male": 12400, "female": 15100, "unknown": 200 }] }],"targeting": { "ages": "18-65+", "gender": "All", "locations": ["Germany", "France"], "euTotalReach": 284000 }}
Derived audience analytics
audienceAnalytics is computed entirely from the euTotalReach and ageGenderCountryBreakdown fields above — nothing here comes from a separate Meta endpoint. It buckets total reach into a reachTier (e.g. "100K-1M"), names the topCountry and its reach, counts distinct countries, and labels genderSkew and ageSkew ("male"/"female"/"balanced", "younger"/"older"/"balanced") from the real male/female/age-band counts. It populates wherever the raw breakdown does, and is null elsewhere — a quick read on audience shape without writing your own aggregation over the raw array.
How does Facebook Ads Library Scraper: Ad Reach By Region & Age differ from the official Meta Ad Library API?
Meta publishes its own Ad Library API, which returns the same underlying transparency disclosures — spend, impressions, and demographic/region reach — for political, social-issue, election and EU-served ads, but access requires a Meta developer app and, for political-ad data in many countries, identity verification.
| Feature | Meta Ad Library API | This Actor |
|---|---|---|
| Ad categories covered | Political, social-issue, election & EU-delivered ads | Any public ad reachable via a Page URL or Ad Library search link, with automatic political/issue detection |
| Access setup | Meta developer app + access token; identity verification for political-ad access in eligible countries | An Apify account only — no Facebook login, developer app, or ID check |
| Query input | Structured API parameters you must construct yourself | A pasted Facebook Page URL or Ad Library search URL |
| Reach & demographic breakdown | Age/gender/region reach figures on the disclosed ad set | Same disclosed figures, re-emitted as euTotalReach / ageGenderCountryBreakdown, plus a derived audienceAnalytics summary |
| Funder/payer transparency | funding_entity-style field on political/issue ads | payer / beneficiary fields from the same disclosure |
| Output format | Raw Graph API JSON | Normalized dataset JSON, exportable as JSON, CSV or Excel |
The official API is the right choice for an approved developer building a compliance system directly against Meta's endpoint. This Actor is the faster path when you just want those same disclosed reach and spend figures in a dataset, without registering an app or waiting on identity verification.
What is the difference between an ad reach breakdown and ad targeting data?
They answer different questions, and Facebook Ad Library scrapers checked during this Actor's competitor review only cover one of them. Reach data — euTotalReach, ageGenderCountryBreakdown, targeting — describes who an ad actually reached after it ran, broken down by age, gender and country, because Meta is required to disclose it for EU-served and political/issue ads. Targeting data would describe the interests, behaviors or custom audiences an advertiser chose before the ad ran — but Meta does not disclose that level of detail through the Ad Library at all, to any scraper or API. The targeting field this Actor returns is still reach-based (who the ad reached, by broad age/gender/location bands), not the advertiser's original targeting strategy. Two of the three competing Facebook Ad Library scrapers reviewed for this Actor surface spend, impressions and creative fields but not the age/country/gender reach breakdown; none surface original ad-set targeting, because Facebook doesn't publish it.
How to scrape Facebook ads with Facebook Ads Library Scraper: Ad Reach By Region & Age?
- Open the Actor's page on the Apify Store and click Try for free or Run.
- Add one or more entries to
adPageUrls— a Facebook Page URL, an Ad Library search URL, or both. No field is required; leaving it empty returns nothing to scrape. - Set the real query controls that apply:
targetCountry,adStatus, anddateRangefor Page-based sources (Ad Library search links usually already carry their own country and status). - Start the run.
- Download the dataset as JSON, CSV or Excel once the run finishes, or stream it via the Apify API.
A minimal request:
{"adPageUrls": ["https://www.facebook.com/SHEINOFFICIAL"],"maxAds": 25,"includeAudience": true,"includeAudienceAnalytics": true}
How to run multiple queries in one job
adPageUrls accepts one entry per line, so a Page URL and one or more Ad Library search URLs can run in the same job — each line is scraped as its own source, up to the shared maxAds cap (or its own limit if you pass an object like { "url": "...", "limit": 50 } instead of a plain string). There's no separate batch-size input to configure; the entries you list are the batch.
⬇️ Input
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
adPageUrls | No | array | One entry per line — a Facebook Page URL or an Ad Library query link. Also accepts objects with url plus optional label, limit, or period. | ["https://www.facebook.com/SHEINOFFICIAL"] |
maxAds | No | integer | Maximum ads to profile across all sources in the run. Default 10, min 1, max 50000. | 25 |
reachSummaryOnly | No | boolean | Skip per-ad detail and emit one rollup row per advertiser (ad count only). Default false. | false |
deepTransparencyLookup | No | boolean | Run the per-ad transparency lookup that carries EU reach, demographics and funder/spend data. Default true. | true |
includeAdvertiserProfile | No | boolean | For Page advertisers, attach the public page title/description. Default false. | false |
includeAudience | No | boolean | Add euTotalReach, ageGenderCountryBreakdown and targeting to each row. Default true. | true |
includeAudienceAnalytics | No | boolean | Add the derived audienceAnalytics object. Default true. | true |
politicalOnly | No | boolean | Keep only ads carrying political/issue transparency. Default false. | false |
targetCountry | No | string (enum) | Country used to pull reach for Page advertisers. Ad Library query links usually already carry their own country. Default "ALL". | "US" |
dateRange | No | string | Optional delivery window for Page advertisers when the source URL doesn't set one — absolute date or relative span. Default "". | "30 days" |
adStatus | No | string (enum) | Which ads to profile for Page advertisers: all, active, or inactive. Default "all". | "active" |
proxyConfiguration | No | object | Optional Apify Proxy. When enabled, only residential proxy traffic is used for the whole run. | {"useApifyProxy": true} |
Example JSON input:
{"adPageUrls": ["https://www.facebook.com/SHEINOFFICIAL","https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=DE&media_type=all&search_type=keyword_unordered&q=fitness"],"maxAds": 100,"deepTransparencyLookup": true,"includeAudience": true,"includeAudienceAnalytics": true,"politicalOnly": false,"adStatus": "all","targetCountry": "ALL","dateRange": ""}
Common pitfall: targetCountry, adStatus and dateRange only apply as defaults for Page URL sources. If a line in adPageUrls is an Ad Library search URL that already has country=, active_status=, or date_preset= in its query string, that URL's own values win — the top-level input is not applied on top of it.
⬆️ Output
Each run writes one JSON row per ad (or per advertiser, when reachSummaryOnly is on) to the run's default dataset, exportable as JSON, CSV, Excel, or the other formats every Apify dataset supports. The schema is consistent across runs; fields Facebook hasn't published for a given ad are emitted as null rather than omitted or guessed.
Scraped results
[{"adArchiveID": "1198302847561203","pageName": "SHEIN Official","isActive": true,"startDateFormatted": "2026-05-12T00:00:00.000Z","endDateFormatted": null,"inputUrl": "https://www.facebook.com/ads/library/?...&view_all_page_id=134903279948","euTotalReach": 412500,"ageGenderCountryBreakdown": [{ "country": "FR", "age_gender_breakdowns": [{ "age_range": "18-24", "male": 8900, "female": 21400, "unknown": 150 }] },{ "country": "DE", "age_gender_breakdowns": [{ "age_range": "25-34", "male": 11200, "female": 26700, "unknown": 90 }] }],"targeting": { "ages": "18-65+", "gender": "All", "locations": ["France", "Germany"], "euTotalReach": 412500 },"audienceAnalytics": {"euTotalReach": 412500,"reachTier": "100K-1M","topCountry": "DE","countryCount": 2,"genderSkew": { "malePercent": 34.5, "femalePercent": 65.1, "unknownPercent": 0.4, "skew": "female" },"dominantAgeRange": "25-34","ageSkew": "younger"},"isPolitical": false,"payer": null,"beneficiary": null,"spend": null,"impressions": null,"scrapedAt": "2026-07-25T09:14:02.000Z"},{"adArchiveID": "2207741190552314","pageName": "Citizens for Clean Energy","isActive": true,"startDateFormatted": "2026-06-01T00:00:00.000Z","endDateFormatted": null,"inputUrl": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=ALL&media_type=all&search_type=keyword_unordered&q=clean+energy","euTotalReach": 96200,"ageGenderCountryBreakdown": [{ "country": "ES", "age_gender_breakdowns": [{ "age_range": "45-54", "male": 5200, "female": 4800, "unknown": 40 }] }],"targeting": { "ages": "25-65+", "gender": "All", "locations": ["Spain"], "euTotalReach": 96200 },"audienceAnalytics": {"euTotalReach": 96200,"reachTier": "10K-100K","topCountry": "ES","countryCount": 1,"genderSkew": { "malePercent": 52.0, "femalePercent": 47.8, "unknownPercent": 0.2, "skew": "balanced" },"dominantAgeRange": "45-54","ageSkew": "older"},"isPolitical": true,"payer": "Citizens for Clean Energy PAC","beneficiary": "Citizens for Clean Energy","spend": { "lowerBound": 5000, "upperBound": 5999 },"impressions": { "lowerBound": 100000, "upperBound": 199999 },"scrapedAt": "2026-07-25T09:14:07.000Z"},{"adArchiveID": "3390182774610092","pageName": "Local Coffee Roasters","isActive": false,"startDateFormatted": "2026-03-18T00:00:00.000Z","endDateFormatted": "2026-04-02T00:00:00.000Z","inputUrl": "https://www.facebook.com/LocalCoffeeRoasters","euTotalReach": null,"ageGenderCountryBreakdown": null,"targeting": null,"audienceAnalytics": null,"isPolitical": false,"payer": null,"beneficiary": null,"spend": null,"impressions": null,"scrapedAt": "2026-07-25T09:14:11.000Z"}]
The third row shows the honest gap: this US-only, non-EU-served ad carries no EU transparency disclosure, so every reach and analytics field is null — never estimated or backfilled.
How can I use the data extracted with Facebook Ads Library Scraper: Ad Reach By Region & Age?
- Compliance and political-ad researchers: Filter with
politicalOnlyand trackpayer,beneficiary,spendandimpressionsper advertiser to build a funding-transparency dataset without touching the Meta developer console. - Competitive and market intelligence teams: Pull a competitor's Page and read
euTotalReachplusaudienceAnalytics.topCountry/genderSkewto see which regions and demographics a campaign is actually landing in, not just which ads are running. - AI engineers and LLM developers: Issue a Page URL or search query, receive structured JSON with
ageGenderCountryBreakdownandtargetingalready parsed, and pass it straight into an agent or RAG pipeline as grounding context — no HTML parsing required. - Creative and campaign researchers: Combine
startDateFormatted/endDateFormatted/isActivewith the reach fields to see which running ads are reaching the largest or most skewed audiences, as a signal for creative research.
How do you monitor ad reach over time?
Reach and spend monitoring means running the same set of Page URLs or Ad Library queries on a schedule and diffing the results, rather than reading a single snapshot. Between runs, euTotalReach, spend, impressions, and audienceAnalytics.reachTier are the fields that move as an ad continues to run or a campaign shifts budget — isActive and endDateFormatted tell you when an ad stops entirely. Diff euTotalReach and audienceAnalytics.topCountry/genderSkew between runs for the same adArchiveID to catch a campaign expanding into a new country or shifting its age/gender mix; diff spend/impressions ranges on political ads to catch a funding surge.
A practical loop: schedule a run against a fixed list of Page URLs or saved Ad Library searches, keep the previous run's dataset, and compare adArchiveID-matched rows on the fields above — alert when euTotalReach or spend moves past a threshold you set, or when a previously null political-transparency block appears on an ad that wasn't flagged political before. This also catches an advertiser rotating creative under the same Page while the underlying reach keeps climbing, which a one-off snapshot would miss entirely. Apify's built-in Scheduler runs this Actor on a recurring cadence and writes each run to its own dataset, so the comparison is a matter of pulling the last two dataset exports rather than building a separate polling service.
Integrate Facebook Ads Library Scraper: Ad Reach By Region & Age and automate your workflow
Facebook Ads Library Scraper: Ad Reach By Region & Age works with any language or tool that can send an HTTP request.
REST API with Python
import requestsTOKEN = "YOUR_APIFY_TOKEN"ACTOR = "Scrapier~facebook-ads-library-scraper-ad-reach-by-region-age"resp = requests.post(f"https://api.apify.com/v2/acts/{ACTOR}/run-sync-get-dataset-items",params={"token": TOKEN},json={"adPageUrls": ["https://www.facebook.com/SHEINOFFICIAL"], "maxAds": 25},)resp.raise_for_status()ads = resp.json()for ad in ads:print(ad["pageName"], ad["euTotalReach"], ad["audienceAnalytics"])
MCP for query-grounded AI agents
Every Apify Actor, including this one, is callable through Apify's Actors MCP Server, which exposes an Actor as a tool by its ID (Scrapier/facebook-ads-library-scraper-ad-reach-by-region-age). An MCP-compatible client such as Claude Desktop or another MCP-aware agent framework can register the server, call this Actor with a Page URL or search query, and ground its answer in the returned reach and transparency fields instead of the model's own memory.
Scheduled monitoring and delivery
Use Apify's Scheduler to run this Actor on a recurring cadence against a fixed list of sources, then pull each run's dataset via the API to compare against the previous one. There is no built-in webhook push in this Actor's own configuration; polling the dataset (or wiring an Apify webhook on run completion) is the pattern for delivering fresh results into another system.
Is it legal to scrape the Facebook Ads Library?
Yes — the Ad Library is Meta's own public transparency tool, and this Actor retrieves only what any visitor can already see by opening the same Page or search URL in a browser, without logging in. The EU's Digital Services Act (Regulation (EU) 2022/2065) is part of why this reach and demographic disclosure exists at all — it requires large platforms to publish an ad repository covering reach and audience parameters for ads served to EU users. Scraping public data for compliance monitoring or research carries a different risk profile than scraping personal data for other purposes, and bulk collection of any personal data that does appear (such as a payer's name) may still fall under GDPR or similar regimes depending on your jurisdiction and use. Consult your legal team for commercial use cases involving bulk data storage.
Frequently asked questions
Does this Actor extract EU reach by age, country and gender?
Yes — when includeAudience is on and Meta has published transparency data for an ad, euTotalReach, ageGenderCountryBreakdown and targeting carry the real per-country, per-age-band, per-gender figures. These fields are null on ads Facebook hasn't served in the EU or hasn't disclosed reach for — never estimated.
How many results does this Actor return per query?
maxAds caps the run at up to 50,000 ads (default 10) across all sources combined, unless an individual adPageUrls entry sets its own limit. There is no separate per-query result cap beyond this input.
Which countries can I set for reach and delivery filtering?
targetCountry accepts ALL or any of the countries in its enum list (from Argentina to Vietnam) and applies as the default for Page-based sources; an Ad Library search URL that already specifies country= in its query string keeps its own value.
Does this Actor require a Facebook login?
No. It authenticates as a guest — the same access level as an anonymous visitor to facebook.com/ads/library — using a Chrome-TLS-impersonated session to obtain guest cookies. No Facebook username, password, or session token is ever supplied or required.
How does this Actor handle Facebook's anti-bot measures?
It impersonates a real Chrome TLS fingerprint to obtain guest cookies that plain HTTP clients get blocked on, solves Facebook's JavaScript verification challenge when served one, and escalates from a direct connection to residential proxy routing (with a sticky residential mode) if a request is blocked or rate-limited.
Can I filter to only political and issue ads?
Yes — set politicalOnly to true and rows without political/issue transparency (no payer, spend/impressions range, or AAA eligibility signal) are dropped, leaving only ads Meta has flagged as political or issue-related.
What's the difference between deepTransparencyLookup and includeAudience?
deepTransparencyLookup controls whether the Actor makes the extra per-ad detail request at all; includeAudience controls whether that request's reach and targeting fields are attached to the output once it's made. Turning on includeAudience, politicalOnly, or includeAudienceAnalytics automatically forces the detail lookup on, since all three depend on it.
Does this Actor work with Claude, ChatGPT, and AI agent frameworks?
Yes — it's callable as an HTTP endpoint by any agent framework, and it's also reachable through Apify's Actors MCP Server for MCP-compatible clients, so an agent can retrieve live reach and transparency data before generating an answer.
How does this Actor compare to other Facebook Ad Library scrapers?
Checked against other Facebook Ad Library listings on the Apify Store, most return ad copy, creative assets, spend and impressions ranges, or AI-generated ad-copy classifications — but not the per-country age/gender reach breakdown or the payer/beneficiary transparency this Actor re-emits from Meta's own per-ad disclosure.
Can I use this Actor without managing proxies or Facebook credentials?
Yes — the Actor handles guest-session cookies, TLS fingerprinting, and proxy escalation itself. You only need to supply Page URLs or search links; enabling the optional proxyConfiguration routes the whole run through Apify's residential proxies if you want that from the start.
Your feedback
Found a bug, or a transparency field that doesn't match what's on facebook.com/ads/library? Let us know through the Actor's Issues tab on Apify or the Scrapier support channel — reports like this go directly into fixing the scraper.