Meta Ad Library Scraper avatar

Meta Ad Library Scraper

Pricing

from $0.33 / 1,000 ads

Go to Apify Store
Meta Ad Library Scraper

Meta Ad Library Scraper

Meta Ad Library scraper for Facebook and Instagram ads, by keyword, Page ID or URL. Each row has the ad copy, creatives, call to action, advertiser Page, run dates and platforms. Spend and impressions exist only on political and issue ads. $0.34 per 1,000 ads.

Pricing

from $0.33 / 1,000 ads

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

23

Total users

7

Monthly active users

15 hours ago

Last modified

Categories

Features

Limited permissions

Share

Meta Ad Library scraper for Facebook and Instagram ads by keyword, Page, ad ID or URL, and the matching ads come back as rows: the ad copy, the creative URLs, the call to action, the advertiser Page, the run dates and which platforms it ran on. No Facebook login, no Meta API token, nothing to install.

Read this before you buy. Spend and impressions exist only on political and issue ads. A search for a commercial brand comes back with them empty. If spend is what you came for, set the ad category to political and issue ads.

InputKeywords, advertiser Pages (ID, link or exact name), single ad IDs, or Ad Library URLs
OutputOne row per ad: copy, creatives, call to action, advertiser Page, run dates, platforms, and spend and impressions on political ads
Ceiling20,000 ads per search
Account neededNone, and no Meta API token
Price$0.34 per 1,000 ads on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 14,000

🔍 What Facebook Ad Library Scraper does

The inputs mix freely in one run. Keywords search the way the site's own box does. An advertiser's Page, as an ID, a link or its exact name, pulls that advertiser's whole set, the better route for watching a brand. Pasted Ad Library URLs keep their filters, and a single ad's ID returns that ad.

Narrow by country, status, ad category, media type, language, platforms, exact phrase and, for keywords, advertiser. Sort by most recent, or by impressions on political ads.

The dates are an overlap window: ads running at any point in it come back, including ones that started earlier. Either end works alone, and both take a span like "30 days".

includeAdDetails adds the EU transparency block, the advertiser's Page facts and political spend: one extra request per ad, no extra charge. Two more switches read each Page's About tab, its history and its confirmed owner. Count only returns ad counts, not ads.

📋 What data you get from each Meta ad

What you getField
The ad's id, its Ad Library link, and whether it is still runningadArchiveId, adLibraryUrl, isActive
The advertiser PagepageId, pageName, pageUrl, pageProfilePictureUrl, pageCategories, pageLikeCount
When it ranstartDate, endDate, startDateTimestamp, endDateTimestamp
Where it ranpublisherPlatforms
The ad copyadTitle, adBody, caption, linkDescription
The link and the buttonlinkUrl, ctaText, ctaType
The creativedisplayFormat, images, videos, cards
Spend, impressions and reach, on political and issue ads onlyimpressions, spend, currency, reachEstimate, byline, disclaimerLabel, categories
Variants of the same adcollationCount, collationId
AI and sensitive-content flagscontainsDigitalCreatedMedia, containsSensitiveContent
Which of your inputs found itsearchTerm, country
How long it ran, and how many ads Meta reports for your searchdaysRunning, searchMatchCount
Spend, impressions and reach as numbersspendLower, spendUpper, impressionsLower, impressionsUpper, impressionsIndex, reachLower, reachUpper
Carousel size and the variants Meta grouped into the adcardCount, extraTexts, extraImages, extraLinks, extraVideos
The partner Page on a paid partnershipbrandedContentPartner
Meta's labelsstateMediaLabel, pageIsDeleted
The EU transparency block, when you switch it onageGenderBreakdown, regionReach, advertiserAbout, advertiserInstagramUsername, advertiserInstagramFollowers, lifetimeSpendByDisclaimer, euTotalReach, euTargetedLocations, euTargetedGender, euTargetedAgeMin, euTargetedAgeMax, advertiserInstagramVerified, advertiserIsProfilePage, advertiserPageVerification, advertiserPageCoverPhotoUrl
Page history and admin countries, when you switch it onpageCreatedDate, pageHistory, pageAdminCount, pageAdminCountries, pageStateMediaCountry
The Page's confirmed owner, when you switch it onpageOwnerName, pageOwnerAddress, pageOwnerPhone
Product details from the pages the ad links to, an optional add-onproducts
Your own label, when you set onerunLabel

▶️ How to scrape the Meta Ad Library

  1. Open Facebook Ad Library Scraper and click Try for free.
  2. Type a brand into Search terms, or paste an Ad Library link into Ad Library URLs.
  3. Set Country and Ad status. Switch Ad category to political and issue ads if you need spend and impressions.
  4. Set Max ads per search. Start around 25 to see what the rows look like.
  5. Click Start, then download the dataset as JSON, CSV or Excel, or read it from the Apify API.

Start it with nothing filled in and you get one labelled notice row, which is not charged.

💰 How much does it cost to scrape the Meta Ad Library?

$0.34 per 1,000 ads on the Free plan, a little less on paid plans. On the free plan, the $5 Apify gives you each month covers about 14,000 ads.

One billed row per ad delivered, and a count row bills like one. Notice rows, searches that find nothing, includeAdDetails and the two Page switches add nothing. Product data is an optional add-on, billed from 9 November 2026: each product listed on an ad row costs $0.34 per 1,000 on the Free plan, a little less on paid plans. Before that day it is free.

📥 What you give it

{
"searchTerms": ["nike"],
"country": "US",
"activeStatus": "active",
"adType": "all",
"maxResults": 250
}
FieldDefaultWhat it is
searchTermsnone, the box starts at nikeKeywords to search, one per line. One scrape per term.
advertiserPageIdsnoneNumeric Facebook Page IDs, to pull one advertiser's full set.
advertiserPagesnonePage links such as facebook.com/nike, or a Page's exact name. Matched exactly or not at all.
adLibraryUrlsnonefacebook.com/ads/library/ links pasted from the browser. A one-ad link (?id=) returns that ad.
adIdsnoneSingle ad IDs or one-ad links. One row each.
countryUSTwo-letter code for the Ad Library edition, or ALL. A code the Ad Library does not offer stops the run with a free notice; UK is read as GB.
activeStatusactiveAlso inactive, or all for both.
adTypeallpolitical_and_issue_ads for the ads that carry spend and impressions; also housing_ads, employment_ads, credit_ads, which Meta offers in some countries only.
mediaTypeallAlso image, video, meme, image_and_meme or none.
searchTypekeyword_unorderedWords in any order, or keyword_exact_phrase for the phrase as typed.
limitToPageIdsnonePage IDs; your keywords then only return those advertisers' ads.
publisherPlatformsall of themFacebook, Instagram, Messenger, Audience Network, Threads, WhatsApp.
startDate, endDatenoneYYYY-MM-DD, or a span back from today such as 7 days or 3 months. An overlap window; either end works alone.
sortBydefaultmost_recent, or impressions_high, which only reorders political and issue ads.
adLanguagenoneA two-letter code such as es: only ads Meta files under that language.
includeAdDetailsfalseThe EU transparency and advertiser block. No extra charge.
includePageTransparencyfalsePage creation date, name changes, admin count and countries. One request per Page. No extra charge.
includePageOwnerfalseThe business Meta lists as the Page's confirmed owner, with its city and phone where shown. No extra charge.
includeProductDatafalseOptional add-on: name, price, currency, brand, image and rating from up to 10 product pages per ad.
countOnlyfalseOne row per search or Page with Meta's ad count, no ad rows.
dedupeAcrossSearchesfalseAn ad two searches both find comes back once.
maxResults100Ads per search term, Page ID or URL, up to 20,000.
maxResultsTotalnoneA cap for the whole run, on top of the cap per search.
runLabelnoneText copied into every row.
useApifyDatacenterProxyfalseOptional.
proxyConfigurationleave it aloneOptional. Only if you want the run to go out through a particular network of your own.

📤 What you get back

A real row from a run on 20 September 2026, with the long Meta media links cut short:

{
"adArchiveId": "925321173274919",
"adLibraryUrl": "https://www.facebook.com/ads/library/?id=925321173274919",
"isActive": true,
"pageId": "89516513179",
"pageName": "Nordstrom Rack",
"pageUrl": "https://www.facebook.com/NordstromRack/",
"pageProfilePictureUrl": "https://scontent-lga3-3.xx.fbcdn.net/v/t39.35426-6/764807066_...",
"pageCategories": ["Clothing (Brand)"],
"pageLikeCount": 2518019,
"startDate": "2026-08-03",
"endDate": "2026-09-19",
"startDateTimestamp": 1785740400,
"endDateTimestamp": 1789801200,
"publisherPlatforms": ["FACEBOOK", "INSTAGRAM", "MESSENGER"],
"adTitle": "Fast & Free Pickup",
"adBody": "Buy online and pick up in store for free! Get up to 70% off Nike, Vince, Madewell, adidas and more.",
"caption": "Nordstromrack.com",
"linkUrl": "https://fb.com/canvas_doc/1072291375736811",
"linkDescription": "Fast & Free Pickup",
"ctaText": "Learn more",
"ctaType": "LEARN_MORE",
"displayFormat": "VIDEO",
"images": [],
"videos": [{ "videoHdUrl": "https://video-lga3-3.xx.fbcdn.net/o1/v/t2/f2/m366/...", "videoSdUrl": "...", "videoPreviewImageUrl": "..." }],
"cards": [],
"impressions": null,
"spend": null,
"currency": null,
"reachEstimate": null,
"byline": null,
"disclaimerLabel": null,
"categories": [],
"collationCount": 2,
"collationId": "1022906600523558",
"containsDigitalCreatedMedia": false,
"containsSensitiveContent": false,
"searchTerm": "nike",
"country": "US",
"scrapedAt": "2026-09-20T07:04:56.805Z"
}
FieldHow to read it
adBody, adTitle, caption, linkDescriptionThe ad copy as Meta renders it. A plain image ad often has no adTitle.
images, videos, cardsCreative URLs on Meta's own media hosts. cards holds the slides of a carousel, each with its own copy and link.
displayFormatVIDEO, IMAGE, DPA and so on, which is the quickest way to sort creative types.
impressions, spend, reachEstimateMeta's own published transparency figures, only on political and issue ads. They come as bands, strings like ">1M" and "$450K - $500K", never an exact number.
spendLower to reachUpperThe two ends of each band as numbers, currency left in currency. "<100" gives 0 and 100; an open band like ">1M" gives 1000000 and null. impressionsIndex is Meta's own band number, so it sorts. All null where Meta publishes no band.
collationCount, collationIdMeta groups near-identical variants of one ad. This says how many are in the group.
extraTexts, extraImages, extraLinks, extraVideosThe other copy, images, links and videos inside that group, where Meta lists them. Empty on most ads.
daysRunningWhole days from the start date to the end date, or to the moment of the run for an ad still running.
searchMatchCountHow many ads Meta reports for the search. The count stops at 50,001.
stateMediaLabel, pageStateMediaCountryMeta's state-controlled media label, such as "China state-controlled media". null on almost every ad.
pageAdminCountriesCountries of the people who manage the Page, with a count each. Left empty when one person manages it, so only pageAdminCount shows.
pageOwnerName, pageOwnerAddress, pageOwnerPhoneThe business Meta lists as the Page's confirmed owner, as shown in the Page's transparency panel. Each is empty when the panel does not show it.
productsOne entry per product page that published product details: url, name, price, currency, brand, imageUrl, rating, ratingCount.
searchTermWhich of your inputs produced this row: the term, page:<id>, the Page or ad link you gave, or the pasted URL.

🧾 Reading the output

RowHow to spot itBilled
An adIt has an adArchiveId and no _sample keyyes
A count, with Count only onrowType: "count", searchTerm and searchMatchCountyes
A notice_sample: true, _charged: false and a _notice lineno
The time-limit noticeA notice that also carries _code: "TIME_LIMIT" and adsDeliveredno
A stop on an unexpected errorA notice with _code: "UNEXPECTED_ERROR". The ads before it are keptno
A refused inputA notice with _code: "BAD_INPUT" and the field to fix. Nothing was searchedno

Ad rows carry no _charged field. The flag is only on notice rows, to mark them as not real results. Filter on _sample being absent.

Notices tell you something without billing you. They look alike, so read the _notice text.

A run near its time limit stops on its own and keeps what it delivered. It ends as succeeded even if no ad came back.

The Console has three dataset views: overview, creatives and political.

💡 What people use it for

  • Watching a rival brand's creative: their Page ID on a schedule, diffing on adArchiveId.
  • Building a swipe file of ad copy and creatives for one product category, by keyword.
  • Election and issue research, where Meta's published spend and impression bands are the point.
  • Checking which platforms a campaign actually ran on, from publisherPlatforms.

From an ad to the advertiser's front door, in three steps:

  1. Search a product keyword here and group the rows on pageId.
  2. Copy the pageUrl of the advertisers you care about.
  3. Paste them into Facebook Page Contact Info Scraper for each Page's website, e-mail and phone.

🚧 What it does not do

  • No spend or impressions on commercial ads.
  • No exact figures. Even on political ads you get bands, not numbers.
  • No performance data. No click-through rate, no conversions, no return on spend.
  • No creative files. You get URLs on Meta's media hosts, and those expire. Fetch them soon.
  • A broad keyword will not hand you 50,000 ads. Search by advertiser Page ID for depth.
  • No targeting data outside the EU.
  • A Page link must match exactly. A handle unlike the Page's name can miss. You then get a free notice, and the Page ID always works.
  • Product data only where shops publish it. App store links, pages without product details and shops that refuse a plain request give nothing.
  • If the includeAdDetails request fails, the row still arrives without those fields, and is still billed as an ad. Check for the field rather than assuming it is there.
  • Very large runs can hit the platform time limit. Split a big job across several runs.
  • It is not an official Meta tool. Dami's Studio is independent and is not affiliated with or endorsed by Meta, Facebook or Instagram, or by any other company named on this page.

🧭 Which ads scraper do you need?

If you wantUse
Facebook and Instagram ads from Meta's Ad LibraryThis one
The advertiser's Page contact details: website, e-mail, phoneFacebook Page Contact Info Scraper
The advertiser's recent organic Facebook postsFacebook Posts Scraper
The advertiser's Instagram profile and follower countsInstagram Profile Scraper
Ads running on Google Search, YouTube and DisplayGoogle Ads Transparency Scraper
Ads in TikTok's Ad Library, EEA and UKTikTok Ads Scraper

❓ Questions people ask

Do I need a Meta API token or a Facebook login?

No. This reads the public archive.

How do I find an advertiser's Page ID?

You often don't need it: paste the Page's link into advertiserPages. Otherwise read the view_all_page_id= value out of the Ad Library's address bar.

Why is spend empty?

Because the search covered all ads. Switch Ad category to political and issue ads and it fills in.

Does it cover Instagram ads?

Yes, one archive covers every Meta surface. Set publisherPlatforms to Instagram to keep only those.

Can I call it from code or connect it to an AI assistant?

The API tab has code for Python, JavaScript and the CLI. MCP clients like Claude and ChatGPT use https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/meta-ads-library-scraper; coding assistants can load our skill file. All three bill your Apify account at the same price.

Meta publishes it as a public archive, and this reads it as a signed-out visitor sees it: no account, nothing private. Personal data in it, such as a disclaimer name or a Page owner's phone, falls under GDPR, PIPEDA and similar laws, so keep only what you need, and mind anti-spam laws before contacting anyone. Meta's terms still apply to your use. Apify's write-up on scraping and the law is a good starting point, and we are not lawyers.

🆘 If something breaks

Open the Issues tab on the actor page. Send the search term, Page ID or URL you used and the run ID. The _notice line on the notice row usually names the problem on its own.