Meta Ad Library Scraper: Facebook & Instagram Ads avatar

Meta Ad Library Scraper: Facebook & Instagram Ads

Pricing

from $0.70 / 1,000 ads

Go to Apify Store
Meta Ad Library Scraper: Facebook & Instagram Ads

Meta Ad Library Scraper: Facebook & Instagram Ads

Scrape Meta's Ad Library by keyword, advertiser Page or Ad Library URL: ad text, headline, CTA, link, image and video URLs, start date, days running and platforms (Facebook, Instagram, Messenger, Threads), plus EU reach and payer on request. Only-new mode for competitor monitoring. No login.

Pricing

from $0.70 / 1,000 ads

Rating

0.0

(0)

Developer

Michael Costa

Michael Costa

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

a day ago

Last modified

Share

What does Meta Ad Library Scraper: Facebook & Instagram Ads do?

Meta Ad Library Scraper pulls ads from Meta's Ad Library (facebook.com/ads/library) for any search term, advertiser Page or Ad Library URL: the ad's text, headline, button, link, image and video URLs, start date, days running and the platforms it ran on (Facebook, Instagram, Messenger, Threads, WhatsApp, Audience Network). On request it adds EU reach, targeting and who paid. Live, logged out; no Facebook account needed.

Input fields · API · Use it from Claude, ChatGPT or Cursor (MCP)

Jump to: Monitor · Fields · Price · How to use · Input · Output · Switching · AI agents (MCP) · Limits · FAQ

Try it in one click: the input comes pre-filled with the search running shoes in every country, 50 ads. That's 50 ads, or about $0.035 (50 × $0.0007, plus $0.00005 for the run start). Then replace it with what you actually want.

Monitor a competitor's ads: get only new ones, in Slack, email or a webhook

With Only new ads on, each run returns (and charges for) only the ads that search hasn't returned before. A run with nothing new costs only the $0.00005 start fee.

  1. Put the competitor's Page in Advertiser Pages ("pages": ["https://www.facebook.com/nike"]), or a keyword in Search terms, turn on Only new ads ("onlyNew": true), and click Start. This first run returns the current ads (up to Max ads per search) and is the baseline.
  2. Click Save as a new task (top right of the actor page). The memory is kept per input line and filter set (the same Page with another country is a separate search), in the key-value store meta-ad-library-seen in your account, so the task keeps comparing with its own earlier runs.
  3. In Apify Console, open Schedules, click Create new, set how often in Schedule setup (for example daily at 07:00), then Add your task.
  4. On the task, open the Integrations tab and pick where the new ads go:
    • Slack: click Configure, sign in, pick the workspace and channel, and the "run succeeded" event. A useful message: {{resource.statusMessage}} and a link, <https://console.apify.com/storage/datasets/{{resource.defaultDatasetId}}|new ads>.
    • Gmail: click Connect with Google, set the subject and body, and attach the dataset. It sends after each successful run.
    • HTTP webhook: event ACTOR.RUN.SUCCEEDED, your URL. Apify POSTs {"eventType": ..., "resource": {...}}; resource.defaultDatasetId is the run's dataset, and GET https://api.apify.com/v2/datasets/<defaultDatasetId>/items?format=json (with your API token) returns the new ads.

Apify's integrations fire after every successful run, including quiet ones: a quiet run's dataset is empty.

What data does Meta Ad Library Scraper return?

One row per ad:

FieldExampleNotes
id, url3897259703744748, https://www.facebook.com/ads/library/?id=3897259703744748The ad's Library ID and its own Library page
pageName, pageId, pageUrlOn, 238939146624, https://www.facebook.com/On/The advertiser
text, titleDiscover our selection of running shoes..., RunningPrimary text and headline (null when the ad has none)
ctaText, ctaType, linkUrlShop now, SHOP_NOW, http://www.on.com/The button and where it goes
imageUrls, videoUrls["https://scontent...jpg"]Every image and video, carousel and catalogue cards included
cards[{"title": ..., "linkUrl": ..., "imageUrl": ...}]Each card of a carousel, dynamic or catalogue ad
startDate, endDate, daysRunning2026-05-06, 2026-10-14, 162Long-running ads are usually the ones that work
isActive, platformstrue, ["facebook", "instagram", "threads"]
displayFormatIMAGE, VIDEO, CAROUSEL, DCO, DPADCO is dynamic creative, DPA a catalogue ad
versions3How many versions of the same creative Meta groups together
euTotalReach, euReachBreakdown1808715, [{"country": "DE", "ageRange": "25-34", "male": ..., "female": ...}]With Ad details on, for ads shown in the EU
payers, advertiser[{"payer": "...", "beneficiary": "..."}]With Ad details on
spend, impressions, reachEstimate$600K - $700K, >1MPolitical and issue ads only; null otherwise. Always US English, whatever country the request comes from
spendMin, spendMax, currency600000, 700000, USDThe spend range as numbers, ready to sort and sum; impressionsMin/Max and reachEstimateMin/Max likewise (>1M gives a min of 1000000 and no max)

Every result has the same fields; the full list is under Output.

How much does it cost to scrape the Facebook Ad Library?

You pay per ad: $0.70 per 1,000 ads on every Apify plan, plus $0.00005 each time a run starts.

  • The example below: 50 ads × $0.70/1,000 = $0.035, plus the start fee.
  • A month, for example: watching 20 competitor Pages daily with Only new ads, about 5 new ads per Page a day: 20 × 5 × 30 = 3,000 ads ≈ $2.10, plus 30 run starts ($0.0015) for one daily task.
  • Ad details (EU reach, payer, advertiser) cost nothing extra; they make a run slower.
  • Caps: Max ads per search and Max results per run in the input, and Maximum cost per run in the run options. The run stops cleanly at whichever comes first, and stops fetching as soon as the limit is covered: the next page is never requested, so a capped run is also a fast one.

Never charged: searches that fail, ads already returned with Only new ads, and rows without an ad ID, Page or link (they're dropped, not written).

How to scrape the Facebook Ad Library

  1. Open Meta Ad Library Scraper and click Try for free (or Start if you're signed in).
  2. Fill in Search terms, Advertiser Pages or Ad Library URLs (any mix, one per line).
  3. Optionally set Country, Active status, Media type, Platforms, the Shown from / until dates, and Ad details for EU reach.
  4. Click Start, then open the Output tab and export as JSON, CSV or Excel. Ads appear in batches as they're found, not only at the end.

Example: running shoes ads, every country

The pre-filled input:

{"searchTerms": ["running shoes"], "maxAdsPerQuery": 50}

It returned 50 ads, every one with an image or video (local run, 2026-10-14). One of them, a catalogue ad with 6 cards (long values and lists shortened):

{
"id": "3897259703744748",
"url": "https://www.facebook.com/ads/library/?id=3897259703744748",
"query": "running shoes",
"queryType": "keyword",
"pageId": "238939146624",
"pageName": "On",
"pageUrl": "https://www.facebook.com/On/",
"pageLikes": 1272558,
"isActive": true,
"startDate": "2026-05-06",
"endDate": "2026-10-14",
"daysRunning": 162,
"platforms": ["facebook", "instagram", "audience_network", "messenger", "threads"],
"displayFormat": "DPA",
"title": "Running",
"text": "Discover our selection of running shoes and apparel built to go the distance.",
"caption": "on.com",
"linkUrl": "http://www.on.com/",
"ctaText": "Shop now",
"ctaType": "SHOP_NOW",
"imageUrls": ["https://scontent-phl2-1.xx.fbcdn.net/v/t39.35426-6/672676316...", "..."],
"videoUrls": [],
"cards": [
{
"title": "Running",
"text": "Discover our selection of running shoes and apparel built to...",
"linkUrl": "https://www.on.com/en-ph/products/weather-jacket-m-1me1031/m...",
"ctaText": "Shop Now",
"imageUrl": "https://scontent-phl2-1.xx.fbcdn.net/v/t39.35426-6/672676316..."
},
"..."
],
"versions": null,
"euTotalReach": null,
"scrapedAt": "2026-10-14T22:34:43.441630Z"
}

On Apify, the same input took 11 s.

Input

FieldWhat it does
Search terms (searchTerms)Words to search ads for, one search per line. An ad's Library ID finds that ad.
Advertiser Pages (pages)Page address (https://www.facebook.com/nike), Page ID (15087023444) or an Ad Library address with view_all_page_id.
Ad Library URLs (adLibraryUrls)Addresses copied from the Ad Library after searching there, or a single ad's (?id=...). Their filters win; the input fills in what they leave out.
Country (country)Two-letter code (US, GB, DE...) or ALL (the default). UK is read as GB; the Ad Library has no EU-wide filter.
Active status (activeStatus)active (the default), inactive or all.
Ad category (adType)all (the default), political_and_issue_ads, housing_ads, employment_ads, financial_products_and_services_ads.
Media type (mediaType)all, image, video, meme, image_and_meme, none.
Platforms (platforms)Any of facebook, instagram, messenger, audience_network, threads, whatsapp.
Search terms match (searchMode)any_words (the default) or exact_phrase.
Shown from / until (dateFrom, dateTo)Ads shown in that window (YYYY-MM-DD), Meta's own date filter.
Max ads per search (maxAdsPerQuery)Per input line; default 50. Meta lists the most recent ads first.
Max results per run (maxResults)Cap across every search.
Ad details (includeDetails)EU reach, EU targeting, payer and beneficiary, advertiser info. One extra request per ad.
Only new ads (onlyNew)Only ads this search hasn't returned before (how).
{
"searchTerms": ["meal kit"],
"pages": ["https://www.facebook.com/HelloFresh.de", "15087023444"],
"adLibraryUrls": ["https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=protein%20bar&search_type=keyword_unordered&media_type=video"],
"country": "DE",
"activeStatus": "active",
"platforms": ["instagram"],
"dateFrom": "2026-09-01",
"maxAdsPerQuery": 200,
"includeDetails": true
}

Output

Every result has the same fields. Fields the Ad Library doesn't show for an ad are null (or an empty list). A real video ad from a German search URL with Ad details on (local run, 2026-10-14; long links shortened):

{
"id": "2186988382220454",
"adArchiveId": "2186988382220454",
"url": "https://www.facebook.com/ads/library/?id=2186988382220454",
"query": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=DE&media_type=video&q=hellofresh&search_type=keyword_unordered",
"queryType": "url",
"pageId": "161205527314747",
"pageName": "HelloFresh",
"pageUrl": "https://www.facebook.com/HelloFresh.de/",
"pageProfilePictureUrl": "https://scontent-phl2-1.xx.fbcdn.net/v/t39.35426-6/825286349...",
"pageLikes": 2519793,
"pageCategories": ["Food Service"],
"isActive": true,
"startDate": "2026-10-02",
"endDate": "2026-10-14",
"daysRunning": 13,
"platforms": ["facebook", "instagram", "threads"],
"displayFormat": "VIDEO",
"title": "Spare bis zu 120 €",
"text": "Gewöhnlicher Feierabend, genialer Geschmack. Spar bis zu 120 € & lass uns wieder Abendessen!",
"caption": "https://www.hellofresh.de",
"linkUrl": "https://www.hellofresh.de/pages/cook-this-big-idea",
"linkDescription": "Mit dem Code DEB2S131",
"ctaText": "Order now",
"ctaType": "ORDER_NOW",
"imageUrls": [],
"videoUrls": ["https://video-phl2-1.xx.fbcdn.net/o1/v/t2/f2/m366/AQP6PFoMbUN9...mp4"],
"videoPreviewImageUrls": ["https://scontent-phl2-1.xx.fbcdn.net/v/t39.35426-6/825286412...jpg"],
"cards": [],
"versions": 1,
"collationId": "28744967888449010",
"categories": [],
"containsAiContent": false,
"spend": null,
"spendMin": null,
"spendMax": null,
"reachEstimate": null,
"reachEstimateMin": null,
"reachEstimateMax": null,
"impressions": null,
"impressionsMin": null,
"impressionsMax": null,
"currency": null,
"targetedCountries": [],
"euTotalReach": 1808715,
"euTargeting": {"locations": [{"name": "Germany", "type": "countries", "excluded": false}], "ageMin": 18, "ageMax": 65, "gender": "All"},
"euReachBreakdown": [{"country": "DE", "ageRange": "18-24", "male": 21629, "female": 122222, "unknown": 2674}, "..."],
"payers": [{"payer": "HelloFresh SE", "beneficiary": "HelloFresh SE"}],
"advertiser": {"pageAlias": "HelloFresh.de", "pageCategory": "Food delivery service", "likes": 2519793, "verification": "BLUE_VERIFIED", "instagramUsername": "hellofreshde", "instagramFollowers": 215056, "instagramVerified": true, "about": "HelloFresh liefert Dir Kochboxen mit kreativen Rezepten und saisonalen Zutaten frisch zu Dir nach Hau..."},
"scrapedAt": "2026-10-14T22:21:51.291350Z"
}
  • Image and video links are Meta's CDN addresses, which expire after some days: download what you want to keep (for example with Bulk Image Downloader).
  • startDate and endDate are Meta's days in Pacific time, as the Ad Library shows them. For a running ad, endDate is Meta's latest day (usually today) and daysRunning counts to it.
  • id is stable across runs, so you can use it to deduplicate. The run's RUN_STATS record lists every input line, how many ads it returned, the Ad Library address of that search (searchUrl) and anything that failed, with the reason.

Switching from another Ad Library actor?

Most Ad Library tools take the same things the Ad Library's own page does, under other names. Here's where each one goes:

What you hadPut it here
A list of Ad Library search URLs (facebook.com/ads/library/?...)Ad Library URLs (adLibraryUrls), as they are; their country, status, media, platform and date filters are kept
Facebook Page URLs, or "page ads"Advertiser Pages (pages): the address, the numeric Page ID, or an Ad Library view_all_page_id address
KeywordsSearch terms (searchTerms); exact phrase with Search terms match (searchMode: "exact_phrase")
A single ad's link (?id=...) or ad IDAd Library URLs, or the ID as a Search terms line
A limit per URL or per PageMax ads per search (maxAdsPerQuery)
An overall count or "max items"Max results per run (maxResults); the maximum cost per run in the run options holds too
Country code or ALLCountry (country)
Active / inactive / allActive status (activeStatus)
A date period, or "newer than" / "older than"Shown from / Shown until (dateFrom, dateTo), as dates
"Scrape ad details", EU reach, transparencyAd details (includeDetails: true)
Proxy settingsNothing to set: the actor picks its own connection

What's different in the output: one flat row per ad with camelCase fields (pageName, text, ctaText, linkUrl, imageUrls, videoUrls, startDate as a date) instead of Meta's raw snapshot object; card media is listed with the ad's own; daysRunning is computed for you. To reshape rows or rename columns for a sheet, run the dataset through Dataset Transformer.

Run it on a schedule, or from your own code

  1. Save your input as a task (Save as a new task, top right of the actor page) and add it to a schedule (Console → Schedules → Create new).
  2. Collect results: download the dataset as JSON, CSV or Excel; fetch the latest run's results from the API (GET https://api.apify.com/v2/actor-tasks/<task id>/runs/last/dataset/items?status=SUCCEEDED&format=csv, with your API token); let a webhook tell your system when a run succeeds; or connect it to Make, Zapier or n8n through Apify's integrations.

Can I use Meta Ad Library Scraper from an AI agent (MCP)?

Yes, through Apify's MCP server, from Claude, ChatGPT, Cursor or any other MCP client. Add this to your client's MCP configuration (or let the agent find it with the server's actor search); your client signs you in to Apify:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=humble-echidna/meta-ad-library"
}
}
}

To use an Apify API token instead of signing in, add "headers": {"Authorization": "Bearer <APIFY_TOKEN>"} next to url.

An agent should pass what it's looking for and a small cap, e.g. {"pages": ["https://www.facebook.com/allbirds"], "country": "US", "maxAdsPerQuery": 20} or {"searchTerms": ["protein powder"], "mediaType": "video", "maxAdsPerQuery": 30}.

Who it's for

Performance marketers and agencies studying competitors' creatives and offers, media buyers looking for long-running (proven) ads in a niche, e-commerce and DTC brands watching rivals launch new ads, researchers and journalists tracking political, housing or employment ads, and AI agents that need ad copy and creatives on demand.

Why this one?

  • Limits that hold. Max ads per search, Max results per run and your maximum cost per run all stop the run before the next page is fetched, so a run never bills past what you set.
  • Media for every kind of ad. Carousel, dynamic-creative and catalogue ads come with their card images and videos in imageUrls / videoUrls, not just single-image ads. In the example above, all 50 ads had media.
  • EU reach and payer included in the price. Turn on Ad details for EU reach by country, age and gender, EU targeting, payer and beneficiary, and the advertiser's Page and Instagram figures, at no extra charge.
  • Filters apply everywhere. A pasted Ad Library URL keeps its own filters and takes your date range, platforms and the rest where it says nothing.
  • Only new ads for monitoring, remembered per search, and daysRunning to spot ads that have run for months.
  • Fast, no browser. It reads the data the Ad Library page loads: 500 ads took 111 s on Apify (2026-10-14).
  • Reliable. One failing search never affects the others in your run. The run log and the RUN_STATS record say exactly which input line had a problem and why.

Limits

  • What the Ad Library shows logged out, nothing more. Spend, impressions and reach estimates exist only for political and issue ads; EU reach and targeting only for ads shown in the EU. No interest or custom-audience targeting (Meta doesn't publish it).
  • Page addresses are matched through the Page's ads. Logged out, Facebook shows no Page ID, so a Page address (facebook.com/somebrand) is turned into its ID by finding the Page among the Ad Library's advertisers: by its address, or, when the address has changed, by its exact name if only one advertiser has that name (RUN_STATS says which, as pageMatchedBy). If that fails (two Pages with the name, Pages with no ads), the line fails with the reason: paste the numeric Page ID instead (on the Page: About > Page transparency).
  • Media links expire after some days (Meta's CDN). Download what you need to keep.
  • Only new ads stops a search after 3 pages in a row with nothing new, since Meta lists the most recent ads first; a new ad Meta ranks below that isn't returned until it moves up.
  • If Meta changes how the Ad Library page loads its data, searches fail with a message saying so until the actor is updated.

FAQ

The Ad Library is Meta's public transparency archive: anyone can open it without an account. This actor reads the same public data the Ad Library page loads in a browser, logged out: it never signs in, uses no account, cookie or session, and solves no captcha or bot check. Please note: facebook.com's robots.txt disallows automated access for every crawler, and Meta's automated-data-collection terms ask for its written permission; those terms bind people who agree to them as Facebook users, and in Meta v. Bright Data (N.D. Cal., January 2024) the court held that Meta's terms didn't cover logged-out collection of public data. The actor identifies itself honestly (User-Agent HumbleEchidnaApify) and keeps a modest pace. The data is about ads and the Pages that run them; political ads can name the people who paid for them. How you use the data, including any personal data, is up to you and the laws that apply to you (GDPR in the EU). If you're Meta or an advertiser and want something taken down, open an issue.

Is there an official Meta Ad Library API?

Yes, but it needs a Facebook account that has passed Meta's identity confirmation, plus a developer app, and it covers political and issue ads worldwide and ads shown in the EU and UK: ordinary commercial ads that ran only elsewhere (most US ads) aren't in it. This actor covers every ad the Ad Library website shows, with no account.

Why did a search return nothing, or fewer ads than expected?

Usually the filters leave nothing (an inactive status with a recent date range, a platform the advertiser doesn't use) or the Page address couldn't be matched to a Page ID (the reason is in the log; paste the ID). If Meta rate-limits a connection, the search moves to a fresh one before giving up. The run log and the RUN_STATS record name the input line and what happened; every other search in the run is unaffected and failed searches aren't charged. Please open an issue with the input you used if it keeps happening.

Can I get only new results since my last run?

Yes: turn on Only new ads (how).

Can I download the ad images and videos?

The rows carry the image and video addresses. To save the files, send the dataset to Bulk Image Downloader, or download them in your own code before the links expire.

ActorUse it when
Bulk Image DownloaderYou want the ad images saved before Meta's links expire
Website Change MonitorYou also want to know when a competitor's landing page changes
Google Trends ScraperYou want to see whether interest in what they advertise is rising
Dataset DiffYou want ads added and removed between two runs, not just new ones
Dataset TransformerYou want the results flattened into a CSV or Excel sheet your way

Feedback and support

Found a bug, or need a field or filter that isn't here? Open an issue on the Issues tab with the input you used.

Versions

Current version: 0.1. See the Changelog tab for what changed in each version.