Meta Ad Library Scraper | Export & Changes
Pricing
from $0.44 / 1,000 results
Meta Ad Library Scraper | Export & Changes
Export Meta Ad Library creatives by advertiser or keyword. Compare full exports for new, changed and absent ads, with coverage safeguards and source media links.
Pricing
from $0.44 / 1,000 results
Rating
0.0
(0)
Developer
Eli J
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
What you can export
Use this Meta and Facebook Ad Library scraper for creative research and ad archives. Supply an advertiser page ID, exact page name or keywords with country contexts to export available creative text, media links, activity flags and source links.
Compare a compatible full export to emit only new, changed and observed-absent ads. An ended row means disappearance from a completely read query; it is not independent confirmation that a campaign stopped.
Try the shipped prefill
Use the input form's example values for a first run. Prefills are examples, not API defaults; check the billing and limits before starting.
{"advertisers": ["182162001806727"],"searchTerms": [],"countries": ["US"],"activeStatus": "all","maxAdsPerQuery": 40}
Input
| Field | Type | Prefill | What it is |
|---|---|---|---|
advertisers | array of strings | ["182162001806727"] | Numeric page IDs or exact advertiser page names. Names must resolve to one case-insensitive exact name match in public search results; otherwise supply a page ID. |
searchTerms | array of strings | [] | Keyword searches, which can return several advertiser pages. |
countries | array of strings | ["US"] | Two-letter country codes, including US and DE. Each country has its own query. |
activeStatus | string | "all" | all, active or inactive; omitted or null uses all. |
maxAdsPerQuery | integer | 40 | Maximum distinct ads scanned per query and country, including unchanged ads. Omitted or null uses 100; 0 requests no work. |
baselineDatasetId | string | — | Optional read-only resource picker for a previous full export dataset; selecting it switches to change mode. |
Prefills populate the form; they are not API defaults. {}, empty advertisers plus empty search terms, missing/empty countries, or a zero maximum exits successfully with guidance and no ad rows. An Actor start charge may still apply. Invalid inputs fail with a concise explanation, without dataset error rows.
Numeric page IDs give exact advertiser selection. Name resolution checks case-insensitive exact names among the initial public keyword results; a name absent from that sample or matching multiple pages requires a page ID. Keyword results are never presented as an exact advertiser match.
Output
Each row represents an ad in one query and country. The same ad can appear in several query contexts. Within a query, duplicates are removed using adArchiveId.
{"adArchiveId": "1234567890","pageId": "182162001806727","pageName": "adidas","startDate": 1759708800,"endDate": 1760054400,"isActive": true,"platforms": ["FACEBOOK", "INSTAGRAM"],"creativeText": ["Example creative text"],"creativeTitle": ["Example title"],"cta": ["Shop now"],"landingUrls": ["https://example.com/product"],"mediaUrls": ["https://example.com/image.jpg"],"country": "US","sourceUrl": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&search_type=page&view_all_page_id=182162001806727","scrapedAt": "2026-10-05T17:00:00Z","changeStatus": "changed","changedFields": ["creativeText"]}
The example is illustrative. Export rows omit changeStatus and changedFields. Start and end dates are the library's Unix timestamps in seconds, or null when absent. An active ad can have an end date; isActive is the source activity flag. Creative text, titles, CTA text, landing URLs and media URLs are distinct string arrays, including supplied carousel/card values. Missing values produce empty arrays. Landing URLs can include tracking links; the Actor does not follow them. country is search context, not an independently verified targeting claim. sourceUrl links to the query; scrapedAt is this run's UTC observation time.
Media URLs expire. Reacquire them on later runs and dedupe ads using the archive ID, never a media URL. Change comparisons use host-independent media paths and ignore query strings, fragments and array ordering; raw media URLs are exported unchanged, so CDN host rotation alone does not create changed ads. Only explicitly selected advertiser and creative fields are exported; page administrators, commenters and other personal data are excluded.
Change feed
Select a previous full export in baselineDatasetId and use the same advertisers/search terms, country contexts and active-status filter. The Actor reads that dataset and never writes to it. An empty baseline makes all current ads new. Malformed rows, duplicate ad/query identities, other query contexts and change-feed datasets are refused.
new: the archive ID was absent from that query's baseline.changed: a page, date, activity, platform, creative, CTA, landing or media field differs.changedFieldslists the changed output field names. Observation time is excluded.ended: a baseline ad was absent after that query's pagination reached its end. The row retains its last observed fields and refreshesscrapedAt. This means absent from the selected query/filter, not independent confirmation that the advertiser stopped the ad. With an active-only filter, disappearance can reflect inactivity; with other filters, it can reflect library removal or query membership changes.
An interrupted scan emits no ended rows. A charge limit during delivery after a completed scan can truncate its ended rows; coverage stays complete, the stop reason becomes charge-limit, and a warning counts withheld ended rows. A current row the limit refuses is warned separately. A source-provided terminal page must be fully processed, including all collated ads, before coverage is complete. Unchanged ads emit no change rows but count toward the scan cap. Use a fresh full export as the next baseline; a change dataset is not a complete inventory.
Baseline access follows Apify's Actor permissions: "they can access storages that users explicitly provide via the Actor input" and "the run token is expanded to allow only the requested operations on the selected storages". Its input-schema resource contract defines a string dataset resource with resourcePicker and ["READ"].
Coverage and billing
The COVERAGE key-value record lists each query's complete or partial coverage, distinct ads scanned and stop reason (end, cap, source-error, or charge-limit). The ERRORS record holds handled failures, never billable rows. Every output row uses the pay-per-event dataset push; the Actor stops fetching when the customer's charge limit binds. Unchanged ads incur no dataset-row event. See the Store pricing panel for current prices.
Queries use the public anonymous Ad Library website, without signing in or using the official identity-confirmed API. Document challenges are handled in the same anonymous session; source non-answers retry on fresh sessions, with a bounded three-attempt budget. Each attempt allows at most maxAdsPerQuery continuation requests; fresh cursors containing only duplicates cannot fetch indefinitely. Platform runs use residential egress because the measured datacenter continuation returned a rate-limit error. Source operations can change, so complete coverage is a run observation rather than a guarantee of every ad Meta holds. Large advertisers may need a higher cap and more time. Facebook's robots policy restricts anonymous crawling on these surfaces.
Download the dataset as JSON, CSV or Excel, or read its items through the Apify API. For change tracking, retain the complete full-export dataset you selected as the baseline.