Facebook Ad Library Scraper | Meta Ads, 21 Fields, No Login avatar

Facebook Ad Library Scraper | Meta Ads, 21 Fields, No Login

Pricing

from $3.40 / 1,000 ads

Go to Apify Store
Facebook Ad Library Scraper | Meta Ads, 21 Fields, No Login

Facebook Ad Library Scraper | Meta Ads, 21 Fields, No Login

Scrape Facebook & Instagram Ad Library by keyword or advertiser. Get ad copy, image and video creative URLs, CTAs, run dates & platforms. No login, no API key. Download creatives at scale. Works in Claude, ChatGPT & any MCP AI agent.

Pricing

from $3.40 / 1,000 ads

Rating

0.0

(0)

Developer

The Mine Works

The Mine Works

Maintained by Community

Actor stats

1

Bookmarked

44

Total users

9

Monthly active users

a day ago

Last modified

Share

60 Meta ads in 26 seconds: a recorded run searched 3 brand names in the US Ad Library and delivered 60 active ads with copy, CTAs and creative links

From The Mine Works, makers of Threads Scraper and B2B Leads Finder, with over 140,000 runs across 170+ public actors.

Why choose this actor?

  • 60 ads from 3 brand searches in 26 seconds, with no Facebook login. A recorded run searched three brand names in the US Ad Library and delivered 60 active ads in 26 seconds at 512 MB. You need no Facebook account, no Meta developer app and no access token.
  • The creative itself, not just the copy. Of 313 ads in our recent runs, 289 came with image links and 203 with video links, next to the ad text, headline, call to action, landing page, start date and the platforms each ad runs on (Facebook, Instagram, Messenger, Threads, WhatsApp, Audience Network).
  • You pay only for ads delivered. $3.40 to $5.80 per 1,000 ads depending on your Apify plan. Searches that come back empty or blocked are never charged: in that same run, the third brand returned nothing and cost nothing.

Run it on Apify

Part of The Mine Works Marketing, SEO and reviews family: Similarweb Scraper, Google Ads Transparency Scraper, Google News Scraper, Trustpilot Reviews Scraper, Google Trends Scraper, Semrush Scraper.

Try it in one minute

Paste this into the input's JSON tab and start the run. It returns 10 ads currently running in the US for "lab grown diamonds". We run exactly this every day as a health check, and it finishes in about 12 seconds.

{
"searchTerms": ["lab grown diamonds"],
"country": "US",
"adActiveStatus": "active",
"maxAdsPerSearch": 10
}

There are two ways to say what you want. searchTerms takes keywords such as a brand, product or phrase, and matches the ad text of every advertiser, so a brand name also finds creators and resellers who mention it. pageIds takes numeric Facebook Page IDs, such as "153080620724", and returns ads from that one advertiser. You can use both in one run; Page IDs are searched first. The input form comes prefilled with one of each, so clear the one you do not need. country is a two letter code such as US, GB, IN or AE.

Apify's free plan includes $5 of credit every month, which covers about 853 ads at this actor's price (the Free plan rate of $0.0058 per ad, plus the $0.005 start fee on each of 10 runs at the default memory).

Copy to your AI assistant

themineworks/meta-ad-library-scraper on Apify. Searches the public Meta (Facebook and Instagram) Ad Library by keyword or advertiser Page ID and returns one row per ad: advertiser, ad text, headline, call to action, landing page, start date, platforms, format and image and video URLs, with no login. Call ApifyClient("TOKEN").actor("themineworks/meta-ad-library-scraper").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items. Required: searchTerms (list of keywords) or pageIds (list of numeric Facebook Page IDs). Optional: country (default "US"), adActiveStatus ("active" default, "inactive", "all"), adType ("all" default or "political_and_issue_ads"), mediaType ("all" default, "image", "video", "meme"), maxAdsPerSearch (default 10; the Ad Library page holds about 30 ads per search, so use more terms or Page IDs for more), proxyConfiguration (default Apify residential), monitorMode (default false; true delivers and charges only ads not delivered by an earlier run with the same input). Ad rows have no _type; each run also writes one row with _type "summary" and, when ads were delivered, one with _type "info"; neither is charged. Full spec: GET https://api.apify.com/v2/acts/themineworks~meta-ad-library-scraper/builds/default (Bearer TOKEN), which returns inputSchema and readme. Token: https://console.apify.com/account/integrations?fpr=ymnoit&utm_source=apify-readme&utm_medium=referral

Key features

  • Keyword or advertiser search. Search ad text across all advertisers with searchTerms, or pull one advertiser's ads with pageIds. Filter by country, by active or inactive status, by ad type (all ads, or political and issue ads) and by media type (image, video or meme).
  • 20 fields per ad in recent runs. Archive ID, advertiser Page ID, name and link, active flag, start and end dates, platforms, format, ad text, headline, caption, call to action text and type, landing page, variant count, image URLs, video URLs, Ad Library link and capture time.
  • About 30 ads per search. The actor reads the first page of results the Ad Library serves for each keyword or Page ID, which held 22 to 30 ads per search in our runs. maxAdsPerSearch trims that number; to get more ads, add more keywords or Page IDs.
  • Links only, never media downloads. Image and video creative come as Meta CDN URLs. The actor never downloads media, so runs stay small and fast.
  • Built in stop switches. If two searches in a row return no ads, the run stops early instead of working through the rest of your list against a block. A cost guard also ends a run that makes many requests without delivering ads.

How to use it

Basic: ads for one keyword

{
"searchTerms": ["meal kit delivery"],
"country": "US",
"adActiveStatus": "active",
"maxAdsPerSearch": 30
}

30 is about as many as one search returns. Setting maxAdsPerSearch higher does not get more ads from the same search.

Several brands in one run

{
"searchTerms": ["RYZE Superfoods", "Arrae", "Ironmaid"],
"country": "US",
"adActiveStatus": "active",
"maxAdsPerSearch": 45
}

This is the input of our recorded run: 60 ads in 26 seconds. Each keyword is a separate search with its own fresh IP. Keyword search matches ad text, so the "Arrae" search also returned ads from creators who mention the brand. Use pageIds when you want one advertiser's own ads only.

Competitor creative teardown, by Page ID

{
"pageIds": ["107940537227344", "108401623899597"],
"country": "US",
"adActiveStatus": "all",
"maxAdsPerSearch": 30
}

To find an advertiser's Page ID, run a keyword search for the brand first: every ad row carries page_id and page_name. Then track that advertiser by ID. adActiveStatus: "all" includes ads that have stopped running, which shows how long the brand kept each creative live.

Weekly watch on a category

{
"searchTerms": ["lab grown diamond", "moissanite ring", "engagement ring sale"],
"country": "US",
"adActiveStatus": "active",
"maxAdsPerSearch": 30
}

Save this as a task and schedule it weekly (Apify Console, Schedules, Create new). Compare ad_archive_id values with last week's export to see which ads are new and which were switched off. Each run delivers and charges every ad it finds again; add "monitorMode": true to get only the ads you have not received before (see Run it on a schedule).

Several markets for the same brand

The Ad Library is country scoped, so run the same input once per country (US, GB, IN, AE and so on), for example as one saved task per market. An ad running only in Germany will not appear in a US search.

Political and issue ads

{
"searchTerms": ["climate"],
"country": "US",
"adType": "political_and_issue_ads",
"adActiveStatus": "all",
"maxAdsPerSearch": 30
}

This filter limits results to the Ad Library's political and issue category. The rows carry the same fields as any other ad; spend and impression ranges are not extracted.

Input parameters

ParameterTypeDefaultWhat it does
searchTermsarray of stringsnone (prefilled with lab grown diamonds)Keywords. Each one is a separate Ad Library search that matches ad text across all advertisers.
pageIdsarray of stringsnone (prefilled with one Page ID)Numeric Facebook Page IDs. Each one returns that advertiser's ads. Searched before searchTerms.
countrystringUSTwo letter country code of the Ad Library region, such as US, GB, IN, AE.
adActiveStatusstringactiveactive, inactive or all.
adTypestringallall for every ad, or political_and_issue_ads.
mediaTypestringallall, image, video or meme (image and meme ads).
maxAdsPerSearchinteger10Most ads kept from each keyword or Page ID, 1 to 2,000. A search returns about 30, so values above 30 change nothing. Also your cost cap.
downloadImagesbooleanfalseKept for older inputs. Has no effect: image URLs are always returned in image_urls and no media is downloaded.
downloadVideosbooleanfalseKept for older inputs. Has no effect: video URLs are always returned in video_urls.
proxyConfigurationobjectApify residentialProxy for the run. Leave it as it is: Meta challenges datacenter IPs, and the actor only fetches small HTML pages.
monitorModebooleanfalseDeliver only ads not delivered by an earlier run with the same input. Skipped ads are not charged. Made for daily or weekly schedules.

If both searchTerms and pageIds are empty, the run writes only a summary row and charges no ads.

What data do you get?

One row per ad, plus a summary row per run. Ad rows have no _type field.

The advertiser: page_id, page_name, page_url (the Facebook Page link).

The ad: ad_archive_id (Meta's Ad Library ID), snapshot_url (the ad's page in the Ad Library), is_active, start_date, end_date, publisher_platforms (for example FACEBOOK, INSTAGRAM, MESSENGER, THREADS, WHATSAPP, AUDIENCE_NETWORK), display_format (seen in our runs: VIDEO, DCO, IMAGE, DPA, CAROUSEL), collation_count (how many versions Meta groups under this ad).

The creative: ad_body (primary text), ad_title (headline), ad_caption (usually the display domain), cta_text and cta_type (for example "Shop now" and SHOP_NOW), link_url (landing page), image_urls and video_urls (Meta CDN links; video ads also carry their preview image in image_urls).

When: scraped_at, the ISO time the row was written.

A note on dates: Meta gives active ads an end date too, the day you ran the search, so end_date on an active ad means "still running as of this date". Dates are midnight US Pacific time, written in UTC (for example 2026-09-24T07:00:00.000Z).

Summary row (_type: "summary", never charged): ads (delivered), charged_for, charge_failures, yield_guard (with empty_streak, total_empty and yield_guard_tripped, which says whether the run stopped after two empty searches in a row) and scraped_at.

Info row (_type: "info", never charged): written when at least one ad was delivered, with the count and a scheduling tip.

Stable fields for automations

These fields were present in all 313 ad rows of our recent runs. Their names will not change, so a Google Sheet, Zapier zap or n8n flow can map them once.

FieldWhat it is
ad_archive_idMeta's Ad Library ID, the key to store and compare on
page_idAdvertiser's Facebook Page ID
page_nameAdvertiser's Page name
page_urlAdvertiser's Facebook Page link
is_activeTrue while the ad is running
start_dateDate the ad started, ISO 8601
end_dateDate it stopped, or the search date for a running ad
publisher_platformsPlatforms the ad runs on
display_formatCreative format, such as VIDEO or CAROUSEL
cta_typeCall to action code, such as SHOP_NOW
link_urlLanding page
image_urlsImage links; can be an empty list
video_urlsVideo links; can be an empty list
snapshot_urlThe ad's page in the Ad Library
scraped_atWhen this row was written, ISO 8601

ad_caption and cta_text were also in every row. ad_body was missing from 2 of 313 rows, ad_title from 28 and collation_count from 120, because Meta had no value for them, so treat those three as optional. Catalog ads (DCO and DPA) sometimes show Meta's template field names, such as product.name, in ad_body and ad_title instead of real copy, because that is what the Ad Library itself displays.

Output examples

A video ad (recorded run cghR3RKXCUuOiBJW0, US, 24 Sep 2026; CDN links trimmed):

{
"ad_archive_id": "1453706910129969",
"page_id": "107940537227344",
"page_name": "RYZE Superfoods",
"page_url": "https://www.facebook.com/ryzesuperfoods/",
"is_active": true,
"start_date": "2026-07-13T07:00:00.000Z",
"end_date": "2026-09-24T07:00:00.000Z",
"publisher_platforms": ["FACEBOOK", "INSTAGRAM"],
"display_format": "VIDEO",
"ad_body": "RYZE is powered by functional mushrooms and adaptogens. Our creamy and delicious blend features six functional mushrooms, prebiotics, zero added sugar and 100% organic or non-GMO ingredients. ...",
"ad_title": "Pour Yourself a Better Cup of Coffee ☕️",
"ad_caption": "shop.ryzesuperfoods.com",
"cta_text": "Shop now",
"cta_type": "SHOP_NOW",
"link_url": "https://shop.ryzesuperfoods.com/fb",
"collation_count": 1,
"image_urls": ["https://scontent.fcia6-1.fna.fbcdn.net/v/t39.35426-6/742895735_1585698500035948_4695356029445265094_n.jpg?..."],
"video_urls": ["https://video.fcia6-1.fna.fbcdn.net/o1/v/t2/f2/m366/AQPzV2NbuIF0KN3MnF577OC5DRBPhvHho4mbDIeVLpVx1gK6MSkAw..."],
"snapshot_url": "https://www.facebook.com/ads/library/?id=1453706910129969",
"scraped_at": "2026-09-24T08:00:30.480Z"
}

A carousel ad found by a keyword search (recorded run WLT3r1crfueypC8IS, India, 24 Sep 2026; text and links trimmed):

{
"ad_archive_id": "913692170489722",
"page_id": "167389649992739",
"page_name": "Australian Diamond Brokers",
"page_url": "https://www.facebook.com/australiandiamondbrokers/",
"is_active": true,
"start_date": "2024-03-18T07:00:00.000Z",
"end_date": "2026-09-24T07:00:00.000Z",
"publisher_platforms": ["FACEBOOK", "INSTAGRAM", "AUDIENCE_NETWORK", "MESSENGER"],
"display_format": "CAROUSEL",
"ad_body": "Huge range Of 300,000+ Natural and Lab Grown Diamonds. ...",
"ad_title": "Australian Diamond Brokers",
"ad_caption": "australiandiamondbrokers.com",
"cta_text": "Book now",
"cta_type": "BOOK_TRAVEL",
"link_url": "http://www.australiandiamondbrokers.com/",
"collation_count": 1,
"image_urls": [
"https://scontent.fkov1-1.fna.fbcdn.net/v/t39.35426-6/431505730_1092793451764261_5935955348634153424_n.jpg?...",
"https://scontent.fkov1-1.fna.fbcdn.net/v/t39.35426-6/431446828_1445981082948368_627989504511235869_n.jpg?..."
],
"video_urls": [
"https://video.fkov1-1.fna.fbcdn.net/o1/v/t2/f2/m412/AQNTFLF9xz00BsErxwSa7CUVbg5xgSRHJ6mQAx0BQuiGwX3LDTgMIbimO14i84s0uLn3Lh0T75jrbURPXxptwAM.mp4?..."
],
"snapshot_url": "https://www.facebook.com/ads/library/?id=913692170489722",
"scraped_at": "2026-09-24T13:26:16.475Z"
}

The full row had 4 image links and 5 video links, one per carousel card.

An ad with no headline (same run): ad_title is missing because the ad has none.

{
"ad_archive_id": "1189548263302663",
"page_id": "507817735747837",
"page_name": "Starbyjainjewellers",
"page_url": "https://www.facebook.com/61570050003630/",
"is_active": true,
"start_date": "2025-12-23T08:00:00.000Z",
"end_date": "2026-09-24T07:00:00.000Z",
"publisher_platforms": ["FACEBOOK", "INSTAGRAM"],
"display_format": "VIDEO",
"ad_body": "People often ask, “Are lab-grown diamonds fake?” 💎 ...",
"ad_caption": "instagram.com",
"cta_text": "Visit Instagram profile",
"cta_type": "VIEW_INSTAGRAM_PROFILE",
"link_url": "http://instagram.com/starbyjainjewellers",
"collation_count": 1,
"image_urls": ["https://scontent.fkov1-1.fna.fbcdn.net/v/t39.35426-6/593712614_2054003398729145_6428826672116963368_n.jpg?..."],
"video_urls": ["https://video.fkov1-1.fna.fbcdn.net/o1/v/t2/f2/m86/AQNLNoar94LOKfbW0LfsL5PhtvZLbpDd3VTfAoUvYmIQnX4yiIKbACcm8ggSNo1QBT9M1fzHzgZRBb-lj7AdJJ3Vk9WndV_IlVoaXqY.mp4?..."],
"snapshot_url": "https://www.facebook.com/ads/library/?id=1189548263302663",
"scraped_at": "2026-09-24T13:26:14.431Z"
}

The summary row of the recorded run (60 ads, all charged; the Ironmaid search returned nothing, which counts as one empty search):

{
"_type": "summary",
"ads": 60,
"charged_for": 60,
"charge_failures": 0,
"yield_guard": { "empty_streak": 1, "total_empty": 1, "yield_guard_tripped": false },
"scraped_at": "2026-09-24T08:00:50.740Z"
}

A run where Meta returned nothing (our health check run Mi91iOMftzcH2OfYJ, 23 Sep 2026): no ads, no ad charges, only the start fee. A rerun of the same input a minute later returned 10 ads.

{
"_type": "summary",
"ads": 0,
"charged_for": 0,
"charge_failures": 0,
"yield_guard": { "empty_streak": 1, "total_empty": 1, "yield_guard_tripped": false },
"scraped_at": "2026-09-23T09:03:48.063Z"
}

Pricing

Pay per event. You are charged for each ad delivered to your dataset, plus a small start fee per run. The rate falls as your Apify plan rises.

EventFreeBronzeSilverGold and above
Ad delivered (ad-scraped), per ad$0.0058$0.005$0.0042$0.0034
Per 1,000 ads$5.80$5.00$4.20$3.40
Run start (apify-actor-start)$0.005 per GB of run memory, minimum one eventsamesamesame

The start fee, exactly. Apify's apify-actor-start event is charged once when a run starts, one event per GB of memory with a minimum of one. At the default 512 MB, and at 1 GB, that is one event, $0.005 per run. A 4 GB run would pay $0.02. This actor does not need more than 512 MB.

Never charged: searches that return no ads (blocked, empty or no matches), the summary row and the info row. An ad is charged only after it is saved to your dataset.

Charged once per search that finds it: the actor removes repeats within one search, not across searches. An ad that matches two of your keywords is delivered and charged once for each. In a 10 keyword run with overlapping terms ("lab grown diamond" and "lab grown diamonds"), 24 of 219 ads were repeats. Use distinct keywords, or Page IDs, to avoid paying twice.

What real jobs cost on Gold: the recorded run (60 ads) cost $0.204 plus $0.005. A weekly watch of 3 keywords at about 30 ads each costs about $0.31 a week. Ten competitors by Page ID at up to 30 ads each costs up to $1.02 plus $0.005.

There is no price change scheduled for this actor. The Pricing tab on this page always shows the rate for your own plan.

Run it on a schedule

Switch on monitorMode and the actor remembers which ads it has delivered for this input. Each later run delivers only ads you have not received before, which are the ads that went live since the last run, and you pay only for those.

  1. Fill in the input, tick Monitor mode, and save it as a task.
  2. In Apify Console open Schedules, click Add schedule, and pick Daily or Weekly (or a cron such as 0 8 * * 1).
  3. Add the saved task to the schedule and click Save.
{
"searchTerms": ["lab grown diamond", "moissanite ring"],
"country": "US",
"adActiveStatus": "active",
"maxAdsPerSearch": 30,
"monitorMode": true
}

The first run delivers every ad it finds. Each later run with the same input delivers only ads whose ad_archive_id it has not delivered before. Skipped ads are never charged; the start fee applies to every run as usual. The Ad Library page shows about 30 ads per search, so a new ad is caught when it is among them; schedule often enough that new ads do not scroll past. The last row of each run (_type: "info") gives new_this_run, skipped_already_seen and a scheduling tip. The history belongs to the input: change the search terms, Page IDs, country or filters and a new history starts; change maxAdsPerSearch and it carries on. Monitor mode shows new ads, not ads that were switched off; for that, compare two full runs.

FAQ

What is the Meta Ad Library? It is Meta's public archive of ads running on Facebook, Instagram, Messenger, Threads, WhatsApp and the Audience Network, which anyone can search at facebook.com/ads/library without logging in. This actor runs the same searches and returns the results as rows.

How many ads can I get? About 30 per keyword or Page ID: the actor reads the first page of results the Ad Library serves for each search (22 to 30 per search in our runs) and does not page further. For more ads, add more keywords or Page IDs. Each run also stops early if two searches in a row return nothing.

How fresh is the data? Live. Each run searches the Ad Library at the moment it runs. is_active and end_date reflect that day.

Do I need a Facebook account, a Meta developer app or an access token? No. The actor reads the public Ad Library page. There is no login, no app and no token.

Do I need a proxy? No setup is needed. The actor uses Apify's residential proxy by default because Meta challenges datacenter IPs. It fetches only small HTML pages, never images or videos.

Why did a search return no ads? Either nothing matched in that country and status, or Meta refused the request that time. The actor tries each search up to 3 times before moving on, and an empty search is never charged. If a whole run comes back empty, wait a few minutes and run it again: one of our daily health checks returned nothing, and the same input a minute later returned 10 ads.

Does it include spend, impressions or audience data? No. Meta publishes spend and impression ranges only for political and issue ads, and this actor does not extract them even there. You get creative and metadata for every ad type.

Can I download the images and videos? The rows contain direct links in image_urls and video_urls, and you can download from those links yourself. Meta's CDN links expire after a while, so save the files you need soon after the run. The downloadImages and downloadVideos options no longer do anything.

How do I find an advertiser's Page ID? Run a keyword search for the brand: every ad row carries page_id next to page_name. You can also open any of the brand's ads in the Ad Library and read the Page ID there.

How do I get the data out? From the run's Storage tab as JSON, CSV, Excel, XML or HTML, or through the Apify API. CSV and Excel flatten the URL lists into numbered columns.

Can I run it on a schedule or get only new ads? Yes. Save your input as a task and add a schedule in Apify Console (Schedules, then Create new). Set monitorMode to true and each run delivers, and charges, only ads not delivered by an earlier run with the same input.

Can I use it from Claude, ChatGPT or another AI assistant?

  • Connector URL: https://mcp.apify.com/?tools=themineworks/meta-ad-library-scraper.
  • Claude: Settings > Connectors > Add custom connector, paste the URL, sign in with Apify.
  • ChatGPT: developer mode, add an MCP connector with the URL, sign in with Apify.
  • Cursor or VS Code: add it as an HTTP MCP server with that URL.
  • Claude Code: claude mcp add -t http meta-ad-library-scraper "https://mcp.apify.com/?tools=themineworks/meta-ad-library-scraper".

It is also one of the tools inside our E-commerce Intel MCP server, which bundles 8 e-commerce research tools.

Is it legal to scrape the Meta Ad Library? The actor reads only the public Ad Library, a transparency archive Meta makes available to anyone without logging in. Ad creative can still contain personal data, such as a face or a name in a testimonial, and you are responsible for how you use it, including Meta's terms and data protection law such as GDPR and CCPA. This is general information, not legal advice. This actor is independent and not affiliated with or endorsed by Meta.

Integrations

Results land in a standard Apify dataset, so they connect without extra code:

  • Google Sheets: send each run's ads to a sheet with Apify's Google Sheets integration.
  • Make, Zapier and n8n: start a run and read its dataset with the official Apify apps and nodes.
  • Webhooks: get a call to your own URL when a run succeeds, then fetch the dataset.
  • API and SDKs: start runs and read results with the Apify API, or the Python and JavaScript clients.
  • MCP clients: Claude, ChatGPT, Cursor and other MCP clients can call the actor through https://mcp.apify.com/?tools=themineworks/meta-ad-library-scraper.

More from The Mine Works

Marketing, SEO and reviews

Social media and video

Leads and business directories

LinkedIn

Real estate

Science, health and government data

Jobs and hiring

E-commerce and marketplaces

Company and business data

Food and local services

Developer and AI tools

More tools

Support

Found a bug or need a field? Open an issue on the Issues tab of this actor. To ask for a new source, email dmineworks@gmail.com.

Facebook Ad Library Scraper pulls ads from Meta's public Ad Library by keyword or Page ID, with copy, CTAs, landing pages and creative links, no login, from $3.40 per 1,000 ads.