Facebook Ads Library Scraper: Ad Reach By Region & Age avatar

Facebook Ads Library Scraper: Ad Reach By Region & Age

Pricing

Pay per usage

Go to Apify Store
Facebook Ads Library Scraper: Ad Reach By Region & Age

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

Scrapier

Maintained by Community

Actor stats

0

Bookmarked

30

Total users

4

Monthly active users

3 days ago

Last modified

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 audienceAnalytics summary (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 TypeExtracted FieldsPrimary Use Case
Ad identity & statusadArchiveID, pageName, isActive, startDateFormatted, endDateFormatted, inputUrl, scrapedAtKnowing which ads are live, since when, and where the row came from
EU reach & audience breakdowneuTotalReach, ageGenderCountryBreakdown, targetingRegion- and age-level reach intelligence on EU-served ads
Derived audience analyticsaudienceAnalyticsA ready-made reach tier and demographic skew summary without parsing the raw breakdown
Political & issue transparencyisPolitical, payer, beneficiary, spend, impressionsCompliance 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.

FeatureMeta Ad Library APIThis Actor
Ad categories coveredPolitical, social-issue, election & EU-delivered adsAny public ad reachable via a Page URL or Ad Library search link, with automatic political/issue detection
Access setupMeta developer app + access token; identity verification for political-ad access in eligible countriesAn Apify account only — no Facebook login, developer app, or ID check
Query inputStructured API parameters you must construct yourselfA pasted Facebook Page URL or Ad Library search URL
Reach & demographic breakdownAge/gender/region reach figures on the disclosed ad setSame disclosed figures, re-emitted as euTotalReach / ageGenderCountryBreakdown, plus a derived audienceAnalytics summary
Funder/payer transparencyfunding_entity-style field on political/issue adspayer / beneficiary fields from the same disclosure
Output formatRaw Graph API JSONNormalized 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?

  1. Open the Actor's page on the Apify Store and click Try for free or Run.
  2. 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.
  3. Set the real query controls that apply: targetCountry, adStatus, and dateRange for Page-based sources (Ad Library search links usually already carry their own country and status).
  4. Start the run.
  5. 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

ParameterRequiredTypeDescriptionExample Value
adPageUrlsNoarrayOne 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"]
maxAdsNointegerMaximum ads to profile across all sources in the run. Default 10, min 1, max 50000.25
reachSummaryOnlyNobooleanSkip per-ad detail and emit one rollup row per advertiser (ad count only). Default false.false
deepTransparencyLookupNobooleanRun the per-ad transparency lookup that carries EU reach, demographics and funder/spend data. Default true.true
includeAdvertiserProfileNobooleanFor Page advertisers, attach the public page title/description. Default false.false
includeAudienceNobooleanAdd euTotalReach, ageGenderCountryBreakdown and targeting to each row. Default true.true
includeAudienceAnalyticsNobooleanAdd the derived audienceAnalytics object. Default true.true
politicalOnlyNobooleanKeep only ads carrying political/issue transparency. Default false.false
targetCountryNostring (enum)Country used to pull reach for Page advertisers. Ad Library query links usually already carry their own country. Default "ALL"."US"
dateRangeNostringOptional delivery window for Page advertisers when the source URL doesn't set one — absolute date or relative span. Default ""."30 days"
adStatusNostring (enum)Which ads to profile for Page advertisers: all, active, or inactive. Default "all"."active"
proxyConfigurationNoobjectOptional 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 politicalOnly and track payer, beneficiary, spend and impressions per 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 euTotalReach plus audienceAnalytics.topCountry/genderSkew to 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 ageGenderCountryBreakdown and targeting already 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/isActive with 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 requests
TOKEN = "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.

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.