Meta Ad Library Scraper - Facebook & Instagram Ads
Pricing
from $0.55 / 1,000 ads
Meta Ad Library Scraper - Facebook & Instagram Ads
Scrape the Meta Ad Library: Facebook & Instagram ads by keyword, advertiser page or Ad Library URL. Ad copy, CTA, landing page, media, run dates, platforms, plus spend, impressions, demographics and regions for political ads. No login.
Pricing
from $0.55 / 1,000 ads
Rating
0.0
(0)
Developer
Zee Lex
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Meta Ad Library Scraper
Scrape ads from the public Meta Ad Library (facebook.com/ads/library), covering Facebook, Instagram, Messenger and Audience Network ads. Search by keyword, get every ad from an advertiser's page, or paste any Ad Library URL from your browser. No login and no Facebook account needed.
You get the ad copy, headline, call to action, landing page, images, videos, carousel cards, platforms, run dates and number of ad versions. For political and issue ads you also get spend and impression ranges, the "paid for by" disclaimer, and demographic and region breakdowns.
Built for reliability: every ad is validated before saving, rate limits are retried with backoff on fresh sessions, and the run fails with a clear message instead of quietly returning empty or partial data. A search that truly has no ads finishes successfully with a clear "No ads found" status.
Use cases
- Competitor ad research: see every ad a competitor is running, how long each has run, and where it sends traffic
- Creative inspiration: collect ad copy, headlines, images and videos that are working in your niche
- Dropshipping product research: spot products many advertisers are pushing, and long-running ads (a sign they're profitable)
- Agency reporting: track clients' and competitors' ad activity on a schedule
- Political ad transparency: monitor spend, reach and audience breakdowns of political and issue ads
Input
Provide at least one of searchTerms, pageIds, pageUrls or startUrls.
| Field | Type | Default | Notes |
|---|---|---|---|
searchTerms | string[] | – | Keyword search in ad text |
pageIds | string[] | – | Advertiser page IDs (most reliable) |
pageUrls | string[] | – | Advertiser page URLs; the page ID is looked up |
startUrls | URL list | – | Ad Library URLs copied from your browser, all filters kept |
country | string | ALL | 2-letter ISO code (MY, US, GB…) or ALL |
adType | string | all | all or political_and_issue_ads |
activeStatus | string | active | active, inactive or all |
platforms | string[] | all | facebook, instagram, messenger, audience_network |
mediaType | string | all | all, image, video, meme, none |
startDate / endDate | YYYY-MM-DD | – | Ad delivery date range |
maxItems | integer | 100 | Total ads across all inputs |
includePoliticalDetails | boolean | true | Demographic/region breakdown for political ads |
downloadMedia | boolean | false | Save images/videos to the key-value store |
proxyConfiguration | object | Apify Proxy, RESIDENTIAL | Residential strongly recommended |
The filter fields apply to searchTerms, pageIds and pageUrls. startUrls keep their own filters.
Example: keyword search in Malaysia
{"searchTerms": ["air fryer"],"country": "MY","activeStatus": "active","maxItems": 50}
Example: all active ads of one brand
{"pageUrls": ["https://www.facebook.com/nike"],"pageIds": ["15087023444"],"country": "ALL","maxItems": 200}
Tip: the page ID is in the Ad Library URL after view_all_page_id= when you open a brand's ads.
Example: a URL copied from the Ad Library
{"startUrls": [{ "url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&media_type=video&q=skincare&search_type=keyword_unordered" }],"maxItems": 100}
Output sample
One dataset item per ad:
{"adArchiveId": "1111111111111111","adLibraryUrl": "https://www.facebook.com/ads/library/?id=1111111111111111","pageId": "15087023444","pageName": "Philips Malaysia","pageProfileUrl": "https://www.facebook.com/PhilipsMalaysia/","pageLikeCount": 254000,"isActive": true,"startDate": "2025-10-01T00:00:00.000Z","endDate": "2025-10-31T00:00:00.000Z","platforms": ["facebook", "instagram"],"displayFormat": "IMAGE","ctaText": "Shop now","ctaType": "SHOP_NOW","linkUrl": "https://shopee.com.my/philips","displayUrl": "shopee.com.my","title": "Philips Airfryer 3000 Series","bodyText": "Crispy food with 90% less fat. Shop the Philips Airfryer now!","images": ["https://scontent.xx.fbcdn.net/v/...jpg?oh=...&oe=..."],"videos": [],"cards": [],"collationCount": 3,"countries": [],"reachEstimate": null,"political": null,"scrapedAt": "2026-10-27T09:10:00.000Z"}
Carousel ads fill cards: [{ "title", "body", "linkUrl", "caption", "ctaText", "imageUrl", "video": { "hdUrl", "sdUrl", "previewImageUrl" } }].
Video ads fill videos: [{ "hdUrl", "sdUrl", "previewImageUrl" }].
Political and issue ads fill political:
{"spend": { "lower": 100, "upper": 199, "text": "100-199" },"impressions": { "lower": 1000, "upper": 5000, "text": "1K-5K" },"currency": "MYR","paidBy": "Paid for by Example Party","demographicBreakdown": [{ "ageRange": "25-34", "gender": "male", "share": 0.35 }],"regionBreakdown": [{ "region": "Selangor", "share": 0.55 }],"detailsCollected": true}
Field notes:
collationCountis the number of ad versions Meta groups under this ad.countriesandreachEstimateare filled only where Meta publishes them (political ads, and ads delivered in the EU).linkUrlis the real landing page; Facebook's redirect wrapper is removed.sharesin breakdowns are fractions (0.35 = 35%).detailsCollected: falsemeans the breakdown page couldn't be read; the rest of the ad is still saved.- With
downloadMediaon, each ad also getsstoredMedia: [{ "kind", "key", "sourceUrl", "storeUrl" }].
Media URLs expire
Image and video links from Facebook are signed and expire, usually within days. If you need the files later, either download them soon after the run or turn on downloadMedia, which copies up to 5 files per ad into the run's key-value store.
Pricing
Pay per result: $0.70 per 1,000 ads on the Free plan, with lower prices on paid Apify plans (Bronze $0.65, Silver $0.60, Gold and above $0.55 per 1,000). There are no extra platform-usage charges, and you only pay for ads saved to the dataset.
Cost tips
- Set
maxItemsto what you actually need. Results load about 30 ads per scroll. - Narrow with
country,activeStatus,mediaTypeand dates instead of scraping everything and filtering later. - Use
pageIdsinstead ofpageUrlsto skip the page-lookup step. - Turn off
includePoliticalDetailsif you don't need breakdowns; it costs one extra page load per political ad. - Leave
downloadMediaoff unless you need the files.
Reliability and run status
- Ads without an archive ID, advertiser name or Ad Library URL are dropped and counted, never saved. Ads are deduplicated by archive ID across all inputs.
- Login walls, checkpoints, HTTP 403/429, Facebook rate-limit errors (e.g. code 1675004) and empty results where results were expected are detected as blocks. Each is retried on a fresh session with increasing backoff, up to 4 times.
- The run fails with a clear message when:
- no ads were saved although results were expected,
- 20 blocks happen in a row, or
- at least 25% of requests were lost.
- A political ad whose breakdown page stays blocked is still saved without the breakdown, so it doesn't count as lost.
RUN_SUMMARY(linked from the run's Output tab) lists saved and dropped ads, missing-field percentages, block reasons and unresolved page URLs.
Limitations
- The Actor reads Facebook's own web data, which Meta can change at any time. Rising missing-field percentages in
RUN_SUMMARYare the early warning. - Facebook rate-limits aggressively. Datacenter proxies are usually blocked; use RESIDENTIAL proxies. Concurrency is deliberately low (2 pages at a time).
- Looking up a page ID from a page URL can fail when Facebook shows a login screen. Use
pageIdsin that case. - Dynamic/catalog (DPA, DCO) and carousel ads keep their media inside
cards; their top-levelimages/videoscan be empty. - Spend, impressions, demographic and region breakdowns exist only for political and issue ads (and EU-delivered ads where Meta publishes reach). They are not available for ordinary commercial ads.
- Meta shows at most a few thousand ads per search. Use narrower keywords or filters for more.
- Only publicly visible Ad Library data is collected. Meta's terms restrict automated collection; for official, documented access, Meta also offers the Ad Library API for political/issue ads and EU ads. You are responsible for how you use the data.
Development
npm installnpm test # offline parser tests against saved Ad Library responsesapify run # live run using storage/key_value_stores/default/INPUT.json
Offline end-to-end check (serves the fixtures through the browser, no network):
npm run buildMETA_MOCK=1 APIFY_CHROME_EXECUTABLE_PATH=/path/to/chrome node dist/main.js