Facebook Ads Library Scraper - Meta Ads, All Countries
Eimantas V · @amethyst
Scrape the Facebook Ads Library by keyword, Page or Ad Library link, in any country: ad copy, images and videos, landing pages, CTAs, run dates, platforms and the advertiser Page with its likes. Political ad spend included. No login, no token.
About
Facebook Ads Library Scraper pulls ads from Meta's Ad Library, the public archive of every ad running on Facebook, Instagram, Messenger, WhatsApp and Threads. Search by keyword, Facebook Page or any Ad Library link, in any country, and get each ad's copy, images and videos, landing page, call to action, run dates and advertiser Page. No login, no Facebook token, no browser, for one flat monthly rental.
Sephora · "The perfect ballet bun is just a trip to Sephora away." · Shop now -> sephora.com
· video ad, active 65 days, 3 ads share this creative · Facebook, Instagram, Threads · 20.3M Page likes
Benchmark: 300 ads from three advertisers' Pages in 37 seconds; 200 ads from a keyword and two Pages in 30 seconds.
What does Facebook Ads Library Scraper do?
It searches the Ad Library the way you would in your browser, then returns every matching ad as one clean row, ready for a spreadsheet, a swipe file or a competitor dashboard.
- Every country and every ad. Ordinary commercial ads in the US, UK, Canada, Australia and everywhere else, not only political ones or EU ones.
- The full creative. Ad text, headline, description, call to action, landing page, every image and video (HD), carousel cards and the ad's format.
- What is working. How many days each ad has run and how many ads share a creative: long-running, widely used creatives are the advertiser's winners.
- The advertiser. Page name, link, likes, categories and the platforms each ad runs on.
- Political ads. Spend and impressions ranges, currency and "paid for by", parsed into numbers.
- Clean results. An input that cannot be read returns an error row instead of stopping the run; an ad two inputs both find is returned once.
- Built for automation. Start runs through the API and read the results as JSON.
Why it is fast and light
It asks the Ad Library for its own search results directly, 10 ads per request, and never opens a browser. That is why it is quick and uses little compute. Facebook only answers these searches from home-type internet addresses, so the Actor uses the platform's residential proxy automatically; that traffic is about 25 KB per 10 ads.
What data can you extract from the Facebook Ads Library?
| Field | Example | What it is |
|---|---|---|
advertiserName | Sephora | The Facebook Page running the ad |
adText | The perfect ballet bun is just a trip to Sephora away. | The ad copy (all versions, de-duplicated) |
headline, description | We get beauty. | The link headline and description |
ctaText, ctaType | Shop now, SHOP_NOW | The call-to-action button |
linkUrl | https://www.sephora.com/ | The landing page |
imageUrls, videoUrls | ["https://video...fbcdn.net/..."] | Every image and video of the ad (links expire after some days: download what you keep) |
cards | [{ "title": ..., "linkUrl": ..., "imageUrl": ... }] | Each card of a carousel or dynamic ad |
displayFormat | VIDEO, IMAGE, CAROUSEL, DCO, DPA | The ad's format (DCO = dynamic creative, DPA = catalogue ad) |
startDate, endDate, isActive, daysActive | 2026-08-31, "", true, 65 | When it ran and for how long |
collationCount | 3 | Ads sharing this creative |
publisherPlatforms | ["facebook", "instagram", "threads"] | Where it runs |
pageLikeCount, pageCategories, advertiserPageUrl | 20350560, ["Health/beauty"] | The advertiser's Page |
spend, impressions, currency, bylines | { "lowerBound": "1500", "upperBound": "2000" } | Political and issue ads only |
euTotalReach, targetAges, targetGender, ageCountryGenderReachBreakdown | (EU ads) | EU reach and targeting (official API source only; null on website rows) |
snapshotUrl | https://www.facebook.com/ads/library/?id=1797454185033063 | The ad in the Ad Library |
inputQuery, source | https://www.facebook.com/sephora, website | Which input found it, and where the data came from |
How to scrape the Facebook Ads Library
- Under Search keywords or Ad Library links, enter keywords (one per line) or paste any Ad Library address from your browser. Under Facebook Pages, enter the advertisers you want to watch (
https://www.facebook.com/nike,Nikeor a Page id). - Pick Countries (all by default), and any filters: active or stopped ads, media type, platforms, languages, dates, sort order.
- Set Max ads, which also caps the run's compute and proxy use. Max ads per search or Page keeps one big advertiser from using the whole run.
- Start the run, then open its dataset: one row per ad.
How much does it cost to scrape the Facebook Ads Library?
One flat monthly rental, shown on this page, with a free trial. There is no per-ad fee: scrape as many ads as you need.
Runs use your credits for compute and residential proxy traffic, as every Actor does. Measured: 300 ads from three advertisers' Pages in 37 seconds at 512 MB, under 1 MB of proxy traffic, which is about $0.02 per 1,000 ads.
Input
{
"searchQueries": ["running shoes", "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=protein%20bar"],
"pageUrls": ["https://www.facebook.com/sephora", "Gymshark"],
"countries": ["US"],
"activeStatus": "ACTIVE",
"sortBy": "IMPRESSIONS",
"maxResults": 500,
"maxResultsPerQuery": 100
}
| Field | Default | Notes |
|---|---|---|
| Search keywords or Ad Library links | Keywords, Ad Library search links, Page links (view_all_page_id=) or single ads (?id=). A link's own filters win | |
| Facebook Pages | Page address, name or id: every ad the Page runs or ran | |
| Ad Library URLs (other scrapers' format) | startUrls from other Ad Library scrapers, run unchanged | |
| Countries | All | One or more countries where the ads were shown |
| Active status | Active and inactive | Running now, stopped, or both |
| Ad category | All ads | Political and issue, housing, employment, credit |
| Keyword match | Unordered | Or exact phrase |
| Media type | All | Images, videos, memes, none |
| Platforms, Languages | All | Facebook, Instagram, Messenger, WhatsApp, Threads, Audience Network |
| Shown from / until | Only ads shown in this date range | |
| Sort by | Ad Library default | Total impressions, or most recent first |
| Max ads | 50 | Total for the run |
| Max ads per search or Page | 0 (none) | Per-input cap |
| Only count ads | off | Counts instead of ads (official API) |
| Data source | Ad Library website | Or the official API, for EU reach and targeting (ordinary ads only for EU countries) |
Output
Each ad is one row:
{
"adArchiveId": "1797454185033063",
"advertiserName": "Sephora",
"advertiserPageId": "16453004404",
"advertiserPageUrl": "https://www.facebook.com/sephora/",
"adText": "The perfect ballet bun is just a trip to Sephora away.",
"headline": "We get beauty.",
"ctaText": "Shop now",
"ctaType": "SHOP_NOW",
"linkUrl": "https://www.sephora.com/",
"displayFormat": "DCO",
"imageUrls": [],
"videoUrls": ["https://video-phx1-1.xx.fbcdn.net/o1/v/t2/f2/m366/AQOy3VIXrmfzpJHF8wd9..."],
"publisherPlatforms": ["facebook", "instagram", "threads"],
"startDate": "2026-08-31",
"endDate": "",
"isActive": true,
"daysActive": 65,
"collationCount": 3,
"pageLikeCount": 20350560,
"pageCategories": ["Health/beauty"],
"spend": null,
"impressions": null,
"snapshotUrl": "https://www.facebook.com/ads/library/?id=1797454185033063",
"source": "website",
"inputQuery": "https://www.facebook.com/sephora"
}
A political ad adds its ranges, e.g. "spend": { "lowerBound": "1500", "upperBound": "2000" }, "impressions": { "lowerBound": "100000", "upperBound": "125000" }, "currency": "USD", "bylines": "Swamp Fox Solutions".
An input that cannot be read becomes a row with query and error, e.g. a Page name the Ad Library does not know, or an Ad Library link with no search in it.
Tips and limits
- Find a competitor's best ads: their Page, Active only, Sort by: Total impressions, then sort the dataset by
daysActive. - Monitor new ads: schedule a daily run with Sort by: Most recent and a small Max ads.
- Spend is published only for political and issue ads. Meta does not publish what ordinary advertisers spend, so
spendis null for them on every tool. - EU reach and targeting (reach, age and gender breakdowns) come from Meta's official API: choose it as the data source; it returns ordinary ads only for EU countries.
- Media links expire. Meta's image and video links stop working after some days; download the files you want to keep.
FAQ
Is it legal to scrape the Facebook Ads Library?
The Ad Library is a public transparency archive that Meta publishes for anyone to search without logging in, and this Actor reads only what it shows logged out. Meta's terms restrict automated collection and reuse of its data, and ads can contain personal data protected by laws such as the GDPR. Use the results for research and analysis, do not resell them as a dataset, and ask a lawyer if you are unsure. Facebook and Meta are trademarks of Meta Platforms, Inc.; this Actor is not affiliated with or endorsed by Meta.
Can I use it through the API?
Yes. Every run can be started through the API, and its dataset comes back as JSON.
Why did I get fewer ads than I asked for?
The search or Page has fewer matching ads, the run reached Max ads per search or Page, or its timeout. The log says which, and everything collected before that is kept.
Support
Missing a field, or found an Ad Library link that does not work? Get in touch with the input you used, and it will be looked at quickly.
Input
Preview of the input form. Rent the Actor to fill it in and start runs from the console.
searchQueriesOne per line: a keyword (e.g. running shoes) or any Ad Library address copied from your browser: a search with filters, a Page's ads (view_all_page_id=) or a single ad (?id=). Filters in a link override the ones below.
pageUrlsAdvertisers whose ads you want: a Page address (https://www.facebook.com/nike), its name (Nike) or its Page id. Every ad the Page runs or ran is returned, filtered by the options below.
startUrlsThe same as the first field, in the URL-list format other Ad Library scrapers use, so their saved inputs run unchanged. Use either field.
countriesWhere the ads were shown. All countries by default. Pick one or more to narrow it, e.g. US. (The official API source below returns ordinary ads only for EU countries.)
activeStatusRunning now, stopped, or both. An Ad Library link's own setting wins.
adTypeAll ads for competitor research. Political and issue ads add the spend and impressions ranges Meta publishes for them (null on ordinary ads: Meta does not publish what other advertisers spend).
searchTypeUnordered finds ads with all the words in any order; exact phrase only that phrase.
mediaTypeOnly ads with images, videos, memes, or no media.
publisherPlatformsOnly ads shown on these Meta platforms. Empty = all.
languagesOnly ads in these languages. Empty = all.
adDeliveryDateMinOnly ads shown on or after this date (YYYY-MM-DD).
adDeliveryDateMaxOnly ads shown on or before this date (YYYY-MM-DD).
sortByThe Ad Library's order: total impressions (its default, the ads seen most first) or most recent. With a low limit this decides which ads you get.
maxResultsTotal ads for the whole run, across all inputs. It also caps the run's compute and proxy use.
maxResultsPerQueryStop each keyword, link or Page after this many ads, so one big advertiser cannot use the whole run. 0 = no limit per input.
onlyTotalCountReturn how many ads match each input instead of the ads (official API; counts EU and political ads only).
dataSourceAd Library website (default): every country, ordinary and political ads, images, videos, landing pages. Official API: Meta's API, ordinary ads only if they ran in the EU, but adds EU reach, age/gender targeting and reach breakdowns.
proxyConfigNot needed: the website source uses the platform's residential addresses automatically. Add your own proxy URLs only if you want them used instead.
API
Bytewells speaks the Apify API. Existing integrations keep working: point apify-client at https://bytewells.com/api and use your Bytewells API token (Console → Settings → API access). The Actor ID is amethyst/meta-ads-library-scraper (or amethyst~meta-ads-library-scraper in URLs).
JavaScript · apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({
token: process.env.BYTEWELLS_TOKEN,
baseUrl: 'https://bytewells.com/api',
});
const input = {
"searchQueries": [
"Loop Earplugs"
],
"pageUrls": [
"https://facebook.com/Nike"
],
"countries": [
"ALL"
],
"activeStatus": "ALL",
"adType": "ALL",
"searchType": "KEYWORD_UNORDERED",
"mediaType": "ALL",
"publisherPlatforms": [],
"languages": [],
"sortBy": "RELEVANCE",
"maxResults": 50,
"maxResultsPerQuery": 0,
"onlyTotalCount": false,
"dataSource": "website",
"proxyConfig": {
"useApifyProxy": false
}
};
const run = await client.actor('amethyst/meta-ads-library-scraper').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);Python · apify-client
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["BYTEWELLS_TOKEN"], api_url="https://bytewells.com/api")
run_input = {
"searchQueries": [
"Loop Earplugs"
],
"pageUrls": [
"https://facebook.com/Nike"
],
"countries": [
"ALL"
],
"activeStatus": "ALL",
"adType": "ALL",
"searchType": "KEYWORD_UNORDERED",
"mediaType": "ALL",
"publisherPlatforms": [],
"languages": [],
"sortBy": "RELEVANCE",
"maxResults": 50,
"maxResultsPerQuery": 0,
"onlyTotalCount": False,
"dataSource": "website",
"proxyConfig": {
"useApifyProxy": False
}
}
run = client.actor("amethyst/meta-ads-library-scraper").call(run_input=run_input)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)HTTP · curl
curl -X POST "https://bytewells.com/api/v2/acts/amethyst~meta-ads-library-scraper/runs" \
-H "Authorization: Bearer $BYTEWELLS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchQueries":["Loop Earplugs"],"pageUrls":["https://facebook.com/Nike"],"countries":["ALL"],"activeStatus":"ALL","adType":"ALL","searchType":"KEYWORD_UNORDERED","mediaType":"ALL","publisherPlatforms":[],"languages":[],"sortBy":"RELEVANCE","maxResults":50,"maxResultsPerQuery":0,"onlyTotalCount":false,"dataSource":"website","proxyConfig":{"useApifyProxy":false}}'Runs are billed as compute from your credit balance. Paid Actors need an active rental or trial; otherwise the API answers 402 rental-required.
Related
More Actors from the same publisher.

YouTube Channel & Video Scraper
Eimantas V · @amethyst
Scrape YouTube channels and videos without a browser: subscriber counts, full video lists, exact view counts, durations, publish dates, keywords, and optional likes and comment counts.
Social mediaBusinessMarketing$19/mo7-day free trial
Instagram Profile Scraper - Followers, Posts & Emails
Eimantas V · @amethyst
Scrape Instagram profiles by username, URL or ID: exact followers, following and post counts, bio, links, emails and phones from the bio, category, verified and business flags, engagement rate, 12 latest posts and related profiles. No login. From $1.60 / 1,000.
Social mediaLead generationMarketing$19/mo7-day free trial
Google Search Results Scraper - SERP API
Eimantas V · @amethyst
Scrape Google search results by keyword or URL: organic results with real URLs and ranks, places, top stories, knowledge panel, related searches, News and Videos tabs. Optional AI Overview, People also ask and ads. Any country, language or city. From $0.40 per 1,000 pages.
SEO toolsMarketingLead generation$19/mo7-day free trial
Twitter / X Scraper - Tweets, Profiles & Engagement
Eimantas V · @amethyst
Scrape tweets from any public Twitter / X account by handle or URL. Full text, likes, retweets, replies, quotes, bookmarks and view counts, plus hashtags, mentions, expanded links, images and playable video URLs. Retweets carry the original post's engagement. No API key, no browser.
Social mediaLead generationAutomation$19/mo7-day free trial