Facebook Ads Library Scraper | $0.50/1K Starter | Monitor
Pricing
from $0.30 / 1,000 ad saveds
Facebook Ads Library Scraper | $0.50/1K Starter | Monitor
Scrape Facebook and Instagram ads from Meta Ad Library by keyword, advertiser ID or search URL. Export ad copy and image/video links to CSV or JSON. Resume without duplicates, collect across searches and monitor competitor ad changes. $0.50/1K ads on Starter.
Pricing
from $0.30 / 1,000 ad saveds
Rating
0.0
(0)
Developer
Hundevmode Labs
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
1
Monthly active users
a month ago
Last modified
Categories
Security
Limited permissionsShare
Facebook Ads Library Scraper & Competitor Ad Monitor
Collect public Facebook and Instagram ads from Meta Ad Library using keywords, advertiser page IDs or Ad Library search URLs. Export ad copy, image/video links and creative variants to CSV or JSON, continue an interrupted collection without repeating saved IDs, and monitor competitor ad changes.
$0.50 per 1,000 saved ads on Starter. Returned creative links, continuation and monitoring are included. Startup is $0.001 at the default memory; other account-plan rates are listed below.
For agencies, ecommerce teams and researchers who need current ad creatives, advertiser comparisons or structured data for their workflows. No Facebook login or separate ad-data subscription is required.
What you get
- Ad creative research: copy, headlines, CTA, landing links, images, videos and returned creative cards.
- Multiple searches in one run: one total result cap, global deduplication and collection across targets in turn.
- A report for each search: delivered ads, duplicates, completion status and the reason a search stopped.
- Saved continuation: unfinished searches resume; completed searches and already saved ad IDs are skipped.
- Competitor monitoring: compare current observations with the last complete snapshot and export changes.
Media are returned as links, not permanently hosted files. Meta can limit available results or restrict access; use the per-search report to check coverage.
Quick start: scrape Facebook ads
- In Keywords, advertiser IDs or Ad Library URLs, enter your targets, one per line. Replace the example.
- Choose a country and Maximum ads in this run. The limit is shared across all targets.
- Start the Actor. Open Ad results (JSON) or Download flat CSV, then check Results and issues by search.
A keyword search:
{"searchTerms": ["running shoes"],"country": "US","activeStatus": "active","maxResults": 100}
To collect a specific advertiser, paste its numeric Facebook page ID or a search URL containing view_all_page_id. For example:
{"searchTerms": ["15087023444","https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&view_all_page_id=115939511520844"],"country": "US","maxResults": 100,"collectionStrategy": "round_robin"}
A numeric value is an advertiser page ID, not an individual ad archive ID. Keywords can match unrelated advertisers. A company name or domain is not automatically a verified advertiser match.
Facebook and Instagram ad data
The dataset contains one row per unique ad ID. Missing scalar source fields are null.
| Data | Fields |
|---|---|
| Ad and advertiser | adId, adUrl, pageId, pageName, pageUrl |
| Creative copy | adText, headline, description, callToAction, displayFormat |
| Destinations | landingPageUrl, landingPageDomain |
| Images and videos | imageUrl, videoUrl, imageUrls, videoUrls, imageCount, videoCount |
| Creative variants | creativeVariants, creativeVariantCount, primaryCreativeVariantIndex |
| Source status and dates | isActive, startDate, endDate, daysSinceStart |
| Platforms and search context | publisherPlatforms, publisherPlatformsText, requestedCountry, searchTerm, searchTargetIndex, observedAt |
| When published by Meta | currency, spend, reachEstimate, targetedOrReachedCountries |
| In monitoring mode | changeType, firstSeenAt |
A single ad may contain several creative variants. JSON preserves returned cards and image/video lists; the flat CSV includes primary media links and scalar columns for spreadsheets and CRM imports. If top-level copy is missing or templated, primary fields use the first returned creative card. primaryCreativeVariantIndex: 0 identifies that fallback. Variant counts describe returned cards, not all variants in existence.
searchTerm and searchTargetIndex identify the first target that delivered an ad. Overlapping searches do not create extra dataset rows for that ID. A landing domain describes the ad's destination; it does not verify business ownership.
requestedCountry is the requested search country, not proven audience targeting. The source's combined targeting/reach country list does not prove actual reach. daysSinceStart is calendar time since the source date, not active running time or a performance score. Spend and reach may be absent; the Actor does not infer commercial impressions, ROAS or conversions. A source end date does not override the source active-status flag.
Input options and filters
| Input | How to use it |
|---|---|
searchTerms | Main field: keywords, numeric advertiser page IDs or Ad Library search URLs. Up to 50 unique targets in total. |
country | A two-letter country code such as US, GB or DE; ALL requests all available countries. |
maxResults | One total result cap per run, shared across all targets. It is not a cap per keyword or a promise to reach the count. |
collectionStrategy | round_robin (default): one page per unfinished target in turn. sequential: finish searches in input order. |
activeStatus | Active, all available or inactive ads. Historical availability varies by country and category. |
mediaType | All, images and memes, video, or no media, following the source filters. |
adType | All ads or supported political/issue, housing, employment and credit categories. |
exactPhrase | Request an exact keyword phrase instead of an unordered keyword search. |
collectionMode | collect for current results; monitor for snapshot comparison. |
monitorKey | Stable monitoring name for manual/API runs. An Apify Task supplies its identity automatically. |
resumeFromRunId | Continue a finished run using the input provided in PAGINATION.nextInput. |
pageIds, startUrls | Optional additional targets for existing integrations, under the same total cap. |
advanced | Bounded request, time, transfer and no-progress safeguards. |
The default one-page turns spread collection across searches; page sizes and overlapping IDs differ, so counts need not be equal. A small budget or result cap may stop before every target is visited. In input order gives earlier searches priority, so the first broad search can use the whole cap.
Pasted search URLs can override country, status, media, category and keyword/page filters for that target. Standard total-impressions sorting with sort_data[mode]=total_impressions and sort_data[direction]=asc or desc is supported; order comes from Meta. Single-ad URLs, custom requests, remote URL lists, date/language/platform URL filters and other sorting modes are rejected rather than silently ignored. The image filter includes memes; there is no separate meme classifier.
Results and coverage for every search
Open Results and issues by search in Output. Its TARGET_REPORT record lists each target's filters, status, stop reason, pages fetched, returned records, delivered unique ads, delivered ads in this run, skipped duplicates and outstanding buffer count. The same list is included in RUN_SUMMARY.targets.
Statuses are complete, partial, paused and not_started. The one-based targetIndex matches the dataset's searchTargetIndex. Counts accumulate across continuation. adsReturned counts records from fetched pages, including repeated IDs; it is not an estimate of every available matching ad.
A source error or a series of pages without new unique ads pauses only the affected target. Other unfinished searches continue. The run is marked failed if source issues remain, while saved results, the per-target report and continuation remain available. Budget, result, request, time and traffic limits stop the entire run.
coverageComplete means Meta reported no more pages for every requested target. It does not prove the source exposed every ad in existence or that a collection is an atomic snapshot. A successful empty search differs from a failed search. Reports, errors and summaries are stored separately and are not charged as saved ads.
Pagination: continue an interrupted collection
- Open Continue collecting: next input in Output.
- Copy
PAGINATION.nextInputinto a new run of this Actor. - Adjust the result cap, run safeguards or Maximum cost per run if needed. Keep target searches and filters unchanged.
The next run resumes unfinished searches and skips completed ones. Each target retains its own cursor, search session and partly consumed page. Global ad-ID deduplication spans the continuation chain. New-run datasets contain only the new batch; combine datasets to obtain the full collection.
You may change maxResults, collectionStrategy and safeguards during continuation. If a result cap ended mid-page, the remaining rows are delivered before moving to the next target. A source-paused target is attempted again in the next run, not repeatedly scheduled within the same run. If a page has an unusable format or missing ad ID, continuation requests it again while preserving already saved IDs.
Default safeguards allow 120 requests, 240 seconds and 25 MB per run. A target pauses after 10 consecutive pages without new unique IDs; advanced.maxNoProgressPages can change this threshold from 1 to 50. The Apify run timeout must also allow the requested collection time. Raising the threshold can spend more time on empty or duplicate pages.
hasMore means unfinished work remains to attempt, not proof that more ads will be returned. Meta may keep refusing requests, and cursors can expire. A fresh collection starts a new deduplication scope. Older saved checkpoints upgrade automatically; their previously unrecorded per-target history is marked statisticsCoverFullChain: false, while global saved-ID counts are retained.
Monitor competitor ads and creative changes
Save an Apify Task with collectionMode: "monitor" and schedule it in Apify. The Task supplies a stable monitor identity. For manual or API runs, set a stable monitorKey, for example competitor-us.
Monitoring is scoped to your account, Actor, monitor identity and exact searches. It compares advertiser identity, source active status/dates, copy, headlines, destinations, CTA, format, platforms and returned creatives. Spend and reach are exported when present but are not change triggers.
| Change type | Meaning |
|---|---|
BASELINE | First complete collection establishes the reference snapshot. |
NEW | Ad was not present in the previous complete snapshot. |
UPDATED | A tracked field differs from the previous snapshot. |
UNCHANGED | Tracked fields match the previous snapshot. |
NOT_OBSERVED | Ad was absent from this completed search; this does not prove it ended. |
Current observations are exported in the dataset; Monitoring changes opens the separate CHANGES record. Only a complete collection replaces the baseline. A capped or source-partial scan keeps the previous snapshot, and continuation retains observations across batches. Expiring media signatures and regional CDN-host changes alone do not count as creative changes.
Avoid overlapping runs with the same monitoring name. Baseline changes are checked before committing, but this is not a transactional lock. Keep collection limits high enough to finish the monitoring scope. Each fresh monitoring run bills delivered observations, including unchanged ads, at the same rate as collection.
Pricing: saved ads and included features
| Apify account plan | Per 1,000 saved ad observations |
|---|---|
| Free | $0.75 |
| Starter | $0.50 |
| Scale | $0.40 |
| Business | $0.30 |
| Platinum / Diamond discount tiers | $0.30 |
Startup: $0.001 per GB of selected run memory, minimum one event. At the default 256 MB, startup is $0.001, including empty searches. Platform usage is included in the configured PPE policy.
Included: returned creative links/cards, CSV/JSON output, per-search reports, deduplication, saved continuation and monitoring. No separate creative-link or monitoring surcharge. Media files are not downloaded, and optional EU demographic-detail pages are not fetched.
For example, 100 saved ads on Starter at default memory cost 100 × $0.00050 + $0.001 = $0.051. A continuation is a new run with its own startup fee. Each newly delivered unique ad ID is one observation; a later fresh monitoring run that delivers that ad again creates another observation. Skipped duplicates, errors, summaries and standalone change records are not separately billed.
Free accounts have a ceiling of 100 unique ads across a continuation chain, with at most 30 requests, 120 seconds and 10 MB per run. “Free” is the Apify account plan; saved observations still use its PPE rate. The Actor uses the platform account-plan flag and SDK spending limits. Maximum cost per run can stop collection before the result cap. Check the live Pricing tab before running; these are the configured pre-publication rates.
API, n8n and scheduled workflows
Use the Actor's API tab to start runs and retrieve datasets from your application, n8n, Make or other HTTP-capable tools. Apify generates authenticated request examples for your account. For integrations, the stable Actor ID is 6J4u2Rtng2DV9Nivj; the technical name is x_guru/facebook-ads-library-monitor.
Use the dataset for current ad observations, TARGET_REPORT for per-search completion, PAGINATION.nextInput for the next batch, and CHANGES for monitoring changes. An API workflow should inspect completion instead of treating every finished run as full coverage.
Frequently asked questions
Can I scrape Instagram ads too?
Yes, when Meta includes them in the Ad Library results. Returned publisherPlatforms identify the platforms. This Actor collects Ad Library ads; it does not scrape Instagram profiles or posts, and it does not offer an Instagram-only platform filter.
Can I download Facebook ad videos and images?
The Actor returns direct image/video links and returned creative variants. Open or save them in your workflow while they remain available. Signed media URLs can expire; the Actor does not provide permanent media hosting or a downloaded-file archive.
Do I need a Facebook account or an official Meta API token?
No Facebook login or Meta API token is required. The source is the public Ad Library web interface. Your Apify API token is needed only when invoking the Actor through Apify's API. This is an Apify scraping API, not Meta's official Marketing API or access to private campaign metrics.
Can I enter a company website to get its verified advertising page?
Use an advertiser page ID or an Ad Library search URL for a specific page. A company name can be searched as a keyword but may match unrelated ads. Verified domain-to-advertiser matching is not provided.
Why did collection stop below my result limit?
The source may be exhausted or restricted, or the run may reach its money, time, request, transfer or no-progress safeguard. Check Results and issues by search and RUN_SUMMARY.stopReason. Continue using the supplied next input where available. A high requested count is not a completeness or throughput guarantee.
Why are spend, reach or historical ads missing?
Meta's available fields and historical coverage vary by country and ad category. Missing source values remain null; the Actor does not estimate private campaign performance or recover information the source does not expose.
Attribution
Includes the MIT-licensed MetaAdsCollector package by Yossef. See NOTICE.md and the included license. This is an independent tool, not affiliated with Meta or Facebook.