Facebook Ad Library Scraper Pro
Pricing
from $0.49 / 1,000 ad scrapeds
Facebook Ad Library Scraper Pro
Scrape Facebook Ads Library by keyword, page URL, or advertiser name. Returns full creative + CTA + linkUrl + advertiser identity + active dates. 35% cheaper than the leading alternative. No login required, country dropdown, multi-platform/media filters, resume checkpoints.
Pricing
from $0.49 / 1,000 ad scrapeds
Rating
5.0
(1)
Developer
Omar Eldeeb
Maintained by CommunityActor stats
4
Bookmarked
482
Total users
44
Monthly active users
13 days ago
Last modified
Categories
Features
Share
Facebook Ad Library Scraper Pro — Keyword + Page + Advertiser Search
Scrape Facebook's public Ad Library — every ad currently or recently running across Facebook, Instagram, Messenger, and Audience Network. Search by keyword, by page URL, or by advertiser name. Get CTA text, link URLs, full creative (image/video), advertiser info, and active dates.
$0.49 per 1,000 ads. No actor-start fee — you pay only for ads delivered.
No Facebook login required. No developer-app approval. Works on commercial ads, not just political. Country dropdown with 50+ ISO codes. Resume checkpoints pick up an interrupted run where it stopped.
What does Facebook Ad Library Scraper Pro do?
It pulls structured data from facebook.com/ads/library — the public archive of every ad Meta has run on Facebook, Instagram, Messenger, WhatsApp, Threads, and the Audience Network. Unlike the official Meta Ad Library API (political/issue ads only, EU-only, no creative or link data), this actor returns full commercial ads with CTA, link URLs, body text, creatives, and advertiser identity.
Built for marketers, competitive intel analysts, agencies, and researchers who need the same insights Meta surfaces in the Ad Library UI — but at scale, in JSON/CSV/Excel.
Why use Facebook Ad Library Scraper Pro?
- $0.49 per 1,000 ads. No actor-start fee. Compare: the most popular community Facebook Ad Library scraper on the Apify Store charges $0.75 per 1,000 results (Store price checked 2026-09-29).
- Three input modes in one actor. Paste Ad Library search URLs, raw Facebook page URLs (vanity or
profile.php?id=...), or just type akeyword/advertiserNameand we'll build the right URL for you. - Country dropdown with names, not codes. Pick "United States (US)" instead of typing
usorUSand hoping. Or use the Custom country code field for any of the 240+ ISO-3166 codes. - Multi-platform + media-type filters as first-class fields. Filter by FACEBOOK / INSTAGRAM / MESSENGER / AUDIENCE_NETWORK / THREADS / WHATSAPP and image / video / meme / text-only.
- CSV-ready output. Every creative URL, CTA, link, and advertiser field is emitted as a flat column (
linkUrl,ctaText,imageUrl1..5,videoUrl1) — your Sheets import just works. Nested objects preserved for power users. - Dedup'd advertiser About cache. Resolve an advertiser's verified status, categories, and profile pic once per page across the whole run — not once per ad. Saves you money on bulk page scrapes.
- Resume checkpoints. Run timed out, crashed, or stopped? Restart it within 6 hours with the same input — we resume from the last cursor instead of re-charging you for already-scraped ads. A run that finished normally is never resumed, so re-running the same search always returns the full result set.
- EU reach + AAA targeting (optional). Toggle on
Scrape ad detailsto get demographic reach (age × gender × country) and AAA audience metadata for ads Meta labels political or social-issue. - Residential proxy built-in. Default proxy config rotates per request, avoiding the CAPTCHA traps that kill datacenter scrapes.
How to use Facebook Ad Library Scraper Pro
- Open the Apify Console and click Try for free.
- Pick a search style — fastest is to type a Keyword (e.g.,
nike) or Advertiser name (e.g.,Spotify) and pick a Country. - Or paste URLs — Ad Library search URLs (
https://www.facebook.com/ads/library/?...) or raw Facebook page URLs (https://www.facebook.com/ZapierApp). One per line. A page URL returns only that page's ads: the actor looks up the page's Ad Library ID first. This works for vanity URLs,profile.php?id=…,/people/<Name>/<id>/and numeric URLs on any Facebook host (www.,web.,m.,mbasic., language subdomains,fb.me). If the ID can't be looked up (for example an age-restricted brand page), the actor searches the Ad Library by page name and keeps only ads from that exact page. If that finds nothing, the input returns 0 ads with a warning in the log and the run status, and nothing is charged for it. You never get ads from a different advertiser with a similar name. - Set Total ads cap (across the whole run) and/or Limit per input URL to control spend.
- (Optional) Enable Scrape ad details for EU reach, Resolve advertiser About for page-level verification + categories.
- Click Save & Start.
- When the run finishes, export the dataset as JSON, CSV, or Excel from the Storage tab.
Input examples
Keyword search (cheapest, fastest):
{"keyword": "nike","country": "US","mediaType": "video","count": 500}
Page URL — vanity slug:
{"urls": ["https://www.facebook.com/ZapierApp"],"limitPerSource": 200}
Multiple pages + global cap:
{"urls": ["https://www.facebook.com/ZapierApp","https://www.facebook.com/Spotify","https://www.facebook.com/airbnb"],"count": 1000,"resolveAdvertiser": true}
Advertiser-name search across all of Europe with date filter:
{"advertiserName": "Adidas","country": "DE","period": "last30d","mediaType": "video","platforms": ["FACEBOOK", "INSTAGRAM"]}
Migrating from the leading competitor — paste their input shape, we accept it:
{"urls": [{ "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=IN&q=linkedin&search_type=keyword_unordered&media_type=all" }],"count": 100,"scrapePageAds.period": "last7d","scrapePageAds.activeStatus": "all","scrapePageAds.sortBy": "impressions_desc","scrapePageAds.countryCode": "ALL"}
Output
Sample row:
{"adArchiveId": "1234567890123456","adId": "987654321","pageId": "20531316728","pageName": "Nike","isActive": false,"startDate": 1709251200,"endDate": 1713571200,"totalActiveTime": 4406400,"totalActiveTimeSource": "computed_from_dates","publisherPlatform": ["FACEBOOK", "INSTAGRAM"],"country": "US","currency": "USD","displayFormat": "VIDEO","title": "Just Do It.","bodyText": "Run with the new Air Zoom Pegasus 41. Built for breakthroughs.","linkDescription": "Free shipping on orders $50+","ctaText": "Shop Now","ctaType": "SHOP_NOW","linkUrl": "https://nike.com/w/pegasus-41","imageUrl1": "https://scontent.xx.fbcdn.net/v/t39.../creative1.jpg","videoUrl1": "https://video.xx.fbcdn.net/v/t39.../ad-hd.mp4","videoPreviewImageUrl1": "https://scontent.xx.fbcdn.net/v/t39.../preview.jpg","pageVerified": true,"pageCategories": ["Sportswear store"],"pageProfilePictureUrl": "https://scontent.xx.fbcdn.net/v/t39.../profile.jpg","snapshot": { "...full Facebook payload preserved here..." },"runTag": "weekly-pull-2026-05","sourceUrl": "https://www.facebook.com/ads/library/?...&q=nike","scrapedAt": "2026-05-18T14:23:11.482Z"}
Data fields:
| Field | Type | Description |
|---|---|---|
adArchiveId | string | Unique Ad Library archive ID — primary key. |
adId | string | Internal Meta ad ID. |
pageId / pageName | string | Advertiser identity. |
isActive | boolean | Whether the ad is still running. |
startDate / endDate | unix epoch | Start / stop timestamps. |
totalActiveTime | integer | Seconds the ad has been running. Facebook's own figure (second precision) when it sends one, which it only does for very new ads. Otherwise whole calendar days × 86,400, counting both the first and last day (an ad that started today = 1 day). For an ad that is still active the last day is the scrape day; for a stopped ad it is endDate. |
totalActiveTimeSource | string | facebook or computed_from_dates — which of the two totalActiveTime came from. |
publisherPlatform | array | Where the ad runs: FACEBOOK / INSTAGRAM / MESSENGER / AUDIENCE_NETWORK / THREADS / WHATSAPP. |
country | string | ISO country code the ad targets. |
displayFormat | string | IMAGE / VIDEO / CAROUSEL / DCO / etc. |
title / bodyText / linkDescription | string | Ad copy. |
ctaText / ctaType | string | Call-to-action button (Shop Now, SHOP_NOW). |
linkUrl | string | Destination URL of the ad. |
imageUrl1..5, videoUrl1, videoPreviewImageUrl1 | string | Creative CDN URLs, flat. |
spendLowerBound / spendUpperBound / spendCurrency | number/string | Political/social-issue ads only. |
impressionsLowerBound / impressionsUpperBound | number | Political/social-issue ads only. |
pageVerified | boolean | Blue-tick verification status. |
pageCategories / pageProfilePictureUrl | array/string | Advertiser metadata. |
snapshot | object | Full original Facebook payload — preserved for power users. |
advertiser | object | Resolved About-page data (when resolveAdvertiser=true). |
demographicReach | object | EU age × gender × country reach (when scrapeAdDetails=true). |
runTag | string | Echoed from input — useful for joining datasets. |
sourceUrl | string | Which input URL produced this row. |
scrapedAt | ISO 8601 | When we captured the row. |
How much does it cost to scrape Facebook Ad Library?
Pay-per-event pricing — only pay for what you get.
| Event | Price | When it fires |
|---|---|---|
ad-scraped | $0.00049 ($0.49 / 1,000) | Once per ad extracted with creative, CTA, link, body text. |
ad-details-fetched | $0.00025 ($0.25 / 1,000) | Only when scrapeAdDetails=true AND Meta returns non-empty data. EU reach + AAA targeting metadata. Note: Meta publishes EU reach for ads delivered in the EU/UK; this version requests it only for ads Meta labels political or social-issue. Other ads (including commercial ads) come back without reach, and empty calls are never charged. |
advertiser-resolved | $0.001 ($1 / 1,000 unique pages) | Only when resolveAdvertiser=true — fired ONCE per page across the whole run, not per ad. |
There is no actor-start fee. The monthly platform credit on Apify's free plan can be used to test-drive it.
Typical run costs:
| Run | Ads | Details | Advertisers | Cost |
|---|---|---|---|---|
| Sample run | 50 | — | — | $0.0245 |
| Small competitive scan | 500 | — | — | $0.245 |
| 1K-ad market sweep | 1,000 | — | 20 pages | $0.49 + $0.02 = $0.51 |
| 10K-ad campaign analysis | 10,000 | — | 200 pages | $4.90 + $0.20 = $5.10 |
| 10K political/social-issue ads delivered in the EU, with details | 10,000 | up to 10,000 | 200 pages | up to $4.90 + $2.50 + $0.20 = $7.60 |
| 100K-ad agency audit | 100,000 | — | 2,000 pages | $49 + $2 = $51 |
Costs are list prices. With Scrape ad details on, only ads Meta labels political or social-issue get the details call, and it is charged only when Meta returns reach data (EU-delivered ads). Commercial ads never trigger it, so a 10K commercial-ad run with details on still costs $5.10.
Compare: the most popular community Facebook Ad Library scraper on the Apify Store charges $0.75 per 1,000 results (Store price checked 2026-09-29), so the 10,000 ads above would cost $7.50 there vs $4.90 here (35% less per ad).
Tips & advanced options
- Run with the default 256 MB memory. That's enough — peak observed usage is ~60 MB. The actor is capped at 512 MB; more memory would only increase your Apify compute bill without making the scrape faster.
- One source per run beats many small ones. A single keyword/page URL scrape returning 50 ads costs roughly half as much as ten keyword sources of 5 ads each. Bootstrap overhead is per-source. If you need many advertisers, prefer scheduling separate runs over packing 10 URLs into one.
country=ALLreturns ads from every country Meta indexes. Be cautious — the result count can explode for popular keywords.mediaType=videois one of the highest-signal filters for competitive intel — high-spend advertisers ship video creative.platformsfilter is exact-match. Setting["FACEBOOK", "INSTAGRAM"]excludes ads that only run on Messenger or Audience Network.period=last7d+sortBy=most_recentis the fastest way to surface brand-new ad pushes from a competitor.resolveAdvertiser=true+ scraping multiple ads per page costs almost nothing extra — we fire the resolve event once per unique pageId, not per ad. Compare to competitors that re-fetch per ad.- Schedule it. Use Apify Schedules to run weekly with
period=last7dand a stablerunTag, then JOIN datasets bypageIdto track advertiser changes over time. - Chain into other actors. Pipe the dataset into a Shopify, web-archive, or LLM-summarization actor for full competitive-intel pipelines.
- Resume checkpoints. Leave
enableCheckpoint=true(the default). If the run hits its timeout, crashes, a source fails after all retries, or you stop it manually, restart with the same input within 6 hours — sources that already finished are skipped, the rest pick up from the last successful pagination cursor, andlimitPerSourcecounts the ads already delivered. No double-charge. Runs that finished normally (sources exhausted orcountreached) are not resumed: scheduled or repeated runs of the same search start fresh and return every matching ad again. Starting a second identical run while the first is still running gives it a fresh start (it does not take over the running one's checkpoint).
Legal disclaimer
This actor only scrapes data that Facebook makes publicly available in its Ad Library — the same data anyone can see by visiting facebook.com/ads/library. No Facebook login is performed. No private user data is extracted.
Per Meta's Ad Library Terms, ads in the Ad Library are public. However, your jurisdiction's data-protection laws (GDPR, CCPA, etc.) may impose restrictions on how you process advertiser data. You are responsible for compliance with applicable laws in your use of the output.
If you scrape political/social-issue ads, note that some fields (spend range, impressions range, demographic breakdown) are only available for ads in that category — a Meta policy choice.
FAQ & support
Q: Does this work for commercial ads, or only political/issue ads? Yes — works for all ads in the public Ad Library. The official Meta API is restricted to political/issue ads; this actor is not.
Q: The most popular community Ad Library scraper charges $0.75 per 1,000 and you charge $0.49 — is the data the same?
Same source (facebook.com/ads/library), same field coverage. We're cheaper because (a) newer cost structure, (b) we dedup advertiser-About calls per pageId instead of per-ad, (c) we extract the first page free from SSR HTML instead of paying for the GraphQL call.
Q: My country isn't in the dropdown — what do I do?
Use the Custom country code field underneath the dropdown. Type any 2-letter ISO-3166 code (e.g., BD, PK, MA, JM).
Q: I'm getting fewer ads than expected.
(1) Some ads are geo-fenced — try country=ALL. (2) activeStatus=active filters out ended ads — try activeStatus=all. (3) Facebook's pagination occasionally returns empty pages mid-run; our retry logic handles up to 2 consecutive empties before stopping that source.
Q: Can I run this on a schedule?
Yes. Use Apify Schedules + a stable runTag so you can join datasets across runs.
Q: I'm migrating from another Ad Library scraper — will my old input still work?
Yes. We accept the scrapePageAds.period / scrapePageAds.activeStatus / scrapePageAds.sortBy / scrapePageAds.countryCode dot-notation keys as aliases.
For issues: open a ticket on Apify or reach the maintainer through the Apify Store actor page.