Meta Ad Library
Pricing
$1.49 / 1,000 ads
Meta Ad Library
Pricing
$1.49 / 1,000 ads
Rating
0.0
(0)
Developer
Lantern Lab
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Meta Ad Library Scraper (Facebook & Instagram Ads)
Search the public Meta Ad Library by keyword or by advertiser Page and get every ad back as a row: the Library ID and link, the advertiser Page, whether it is still running, start and end date, the platforms it ran on (Facebook, Instagram, Messenger, Audience Network, Threads), the ad text, headline, link, button text, and the image and video URLs. For political and issue ads you also get the spend range, impressions range, currency and the "Paid for by" line. No Facebook login, no login cookies, no account of your own. $1.49 per 1,000 ads, no start fee. See Pricing.
Input:
{"searchTerms": ["running shoes", "election"],"pageUrls": ["https://www.facebook.com/nike"],"country": "US","adType": "all","activeStatus": "active","mediaType": "all","maxItems": 200}
Output - one row per ad (recordType: "ad"); per-target status rows and the run summary are free. Sample from a real run (video URL shortened):
{"recordType": "ad","adArchiveId": "1134693002421653","url": "https://www.facebook.com/ads/library/?id=1134693002421653","pageId": "108107432370909","pageName": "Kalshi - Trade the Headlines","pageUrl": "https://www.facebook.com/KalshiTradeTheHeadlines/","paidForBy": "KALSHI INC.","isActive": true,"startDate": "2026-10-11","endDate": null,"platforms": ["FACEBOOK", "INSTAGRAM"],"countries": [],"searchCountry": "US","displayFormat": "VIDEO","bodyText": "Who will win the House? Trade it on Kalshi.","title": "Trade what's next","linkUrl": "http://itunes.apple.com/app/id1632713844","ctaText": "Install now","imageUrls": [],"videoUrls": ["https://video.xx.fbcdn.net/o1/v/t2/f2/m366/AQP9wr8P….mp4?…"],"collationCount": 2,"impressionsRange": ">1M","spendRange": "$700K - $800K","currency": "USD","searchTerm": "election","rank": 3,"partial": false,"partialReason": null,"collectedAt": "2026-10-24T09:55:03.118Z"}
Limits:
- Public data only. What the Ad Library shows a logged-out visitor: no targeting breakdowns (age, gender, region), no EU reach report, no ad-level demographic data. Spend, impressions and currency exist only for political and issue ads; for every other ad they are
null. - Image and video URLs are Meta's signed CDN links and expire after a few days. Download what you need soon after the run.
- Every search term and Page gets a status row saying what happened. A search that found nothing is an empty result; one cut short by a limit, a refusal or an error is
partialwith the reason - the two are never confused. - Your limits stop collection and appear in the row:
maxItems, themaxUpstreamRequestsrequest ceiling and the maximum charge per run (see Pricing).
What it does
- Searches each keyword and each Page separately and labels every row with the target that produced it (
searchTermorsearchPageId), so one run can cover many brands or topics. - Accepts Pages as a Facebook Page URL, a numeric Page ID, or an Ad Library link with
view_all_page_id. For a Page URL the numeric Page ID is read from the Page's public page first. - Filters the way the Ad Library does: country (or all countries), ad category (all ads, or issues, elections and politics), active / inactive / both, media type, and exact-phrase matching.
- Deduplicates across the whole run: an ad found by several of your search terms or Pages is written once and charged once.
- Keeps the Ad Library's own identifier (
adArchiveId), its start date as the calendar day the Ad Library page shows (startDate, pluspublishedAtas an exact instant) and our collection time (collectedAt) as separate fields.endDateisnullwhile an ad is still running. - Says what happened per target. A search the Ad Library answered with nothing is recorded as an empty result; one that was cut short is marked
partial: truewith the reason. - Caps itself:
maxUpstreamRequestsis a hard ceiling on requests to the Ad Library for the whole run, derived from your input when you leave it empty, so a run is never unbounded. - Charges only ad rows. Empty results, per-target status rows and the run summary are free.
What it does not do
- No login, no account and no session cookies of your own: it reads only what the public Ad Library shows any visitor.
- No targeting or audience data, no EU transparency report, no advertiser contact details.
- It does not download images or videos; it returns their URLs.
- No scheduling or monitoring: one run, one snapshot. Schedule the Actor on Apify if you need a recurring snapshot.
Input
| Field | Default | What it does |
|---|---|---|
searchTerms | – | Keywords or phrases, searched like the Ad Library search box. |
pageUrls | – | Facebook Page URLs, numeric Page IDs, or Ad Library links with view_all_page_id. Give search terms, Pages, or both. |
country | ALL | ALL, or a two-letter country code such as US, GB, DE, BR, JP. |
adType | all | all, or political_and_issue_ads (the only category with spend, impressions and "Paid for by"). |
activeStatus | active | active, inactive or all. |
mediaType | all | all, image, video, meme, image_and_meme, none. |
exactPhrase | false | Match search terms as an exact phrase. |
maxItems | 100 | Most ads one search term or Page may produce (up to 5,000). |
maxUpstreamRequests | derived | Hard ceiling on requests to the Ad Library for the whole run. |
proxyConfiguration | Apify residential | The Ad Library refuses to page results for datacenter IPs, so residential is the default and what the Actor is measured on. |
Output
Three kinds of row, told apart by recordType:
ad- one per ad, the only charged row. Fields as in the sample above, pluspageCategories,pageLikeCount,categories,linkDescription,caption,ctaType,videoPreviewUrls,cardCount(carousel cards),collationIdandreachEstimate.target_status- one per search term or Page:adsReturned,adsCharged,duplicatesSkipped,upstreamRequests,partial,partialReasonand a plain-languagestatusText.RUN_SUMMARY- the last row, also saved asRUN_SUMMARYin the run's key-value store: totals, empty and partial targets by reason, requests sent and why collection stopped.
Partial is not empty
partial: true means a target's results are incomplete, never that it has no ads. partialReason says why:
| Reason | Meaning |
|---|---|
upstream_request_cap | The run reached its maxUpstreamRequests ceiling while on this target. |
charge_limit_reached | The maximum charge you set for the run was reached. |
blocked | The Ad Library refused our requests (rate limit or bot check) even after switching to a new proxy IP. |
upstream_error | A request failed in a way retrying inside the run would not fix. |
page_not_resolved | A Page URL whose numeric Page ID could not be read; pass the numeric ID instead. |
not_collected | The run stopped earlier for one of the reasons above and never reached this target. |
A run that collected nothing because every target was refused ends as failed, not as an empty success.
Limits and boundaries
countrieslists the countries the Ad Library publishes for an ad, which it does for only some ads (mostly EU-delivered and political ones); otherwise it is empty andsearchCountrytells you which country filter found the ad.- The Ad Library returns ads 10 at a time in its own relevance order;
rankis the position in that order for the target. - Ads that share one creative are grouped by the Ad Library (
collationCount); each ad in a group is its own row. - Dynamic-creative ads store template text such as
{{product.name}};bodyText,titleandlinkDescriptionthen carry the first card's text, which is what the Ad Library page shows. Catalog ads whose cards hold template text too keep the template, as the Ad Library itself does (about 2% of rows in our test runs). Tracking placeholders insidelinkUrlare kept as the Ad Library lists them. - A browser is started once per run and reused for every target, so the first target of a run takes a few seconds longer.
Pricing
Pay per event, no start fee:
| Event | Price | Charged for |
|---|---|---|
result | $0.00149 ($1.49 per 1,000) | Each ad row written. Per-target status rows, empty results and the run summary are free. |
Set a maximum charge for the run and the Actor stops before going over it.