Facebook Ad Library Scraper - Meta & Instagram Ads avatar

Facebook Ad Library Scraper - Meta & Instagram Ads

Pricing

from $0.70 / 1,000 ad-scrapeds

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

Facebook Ad Library Scraper - Meta & Instagram Ads

Scrape Facebook & Instagram ads from the Meta Ad Library, no login. Export creatives, EU reach, targeting & political spend, and monitor competitor ads.

Pricing

from $0.70 / 1,000 ad-scrapeds

Rating

0.0

(0)

Developer

yourlocalhost

yourlocalhost

Maintained by Community

Actor stats

0

Bookmarked

9

Total users

2

Monthly active users

4 days ago

Last modified

Categories

Share

Scrape the Meta Ad Library (Facebook & Instagram ads) without login or a Meta API token. This Facebook Ad Library scraper returns every ad as one complete row — creative, copy, CTA, advertiser, dates, placements, political spend ranges, and the full EU DSA transparency data (total reach, reach by age/gender/country, targeting, payer and beneficiary). Built for competitor ad research and recurring ad monitoring, with a monitor mode that reports which ads are new, which stopped, and how long each has been running — the change tracking the Ad Library itself doesn't give you.

Runs on fast HTTP (no browser), so it's cheap and reliable, with Apify scheduling, API access, integrations, and proxy rotation built in.

  • ✅ Facebook & Instagram ads from the public Meta Ad Library
  • ✅ No login, no cookies, no Meta Ad Library API token
  • ✅ EU ad transparency (reach, targeting, payer) in every row
  • ✅ Monitor mode — track a competitor's ads over time
  • ✅ One flat row per ad, stable versioned schema, ready for the API, Google Sheets and AI agents

What you can do with it

  • Competitor ad research / ad spy — pull every ad a brand is running on Facebook and Instagram, with full copy, media, CTAs and landing domains.
  • Ad creative inspiration — browse and export winning creatives by keyword or industry.
  • Political & issue ad transparency — spend and impression ranges, plus EU reach and targeting under the Digital Services Act (DSA).
  • E-commerce & dropshipping research — find which products and offers competitors are promoting.
  • Agency & marketing reporting — scheduled exports to dashboards, Google Sheets, Slack, Make or n8n.
  • AI agents & data pipelines — a stable, versioned field contract and output schema that work through the Apify API and the Apify MCP server.

It reads only public, logged-out Ad Library data. No Facebook account, cookies or tokens are used.

How to scrape the Facebook Ad Library

  1. Enter one or more search terms (e.g. nike) or advertisers (a Facebook page URL, handle, or numeric page ID).
  2. Pick countries (ISO-2 codes like US, DE, or ALL).
  3. Leave Include ad details on to get EU transparency and advertiser enrichment.
  4. Click Start. Results stream to the dataset; a per-query coverage report is saved to the key-value store as SUMMARY.

The default input (nike, US) finishes in under a minute.

Input

FieldTypeDescription
searchTermsstring[]Keywords or brand names. Each term is one query.
searchMatchenumunordered (all words, any order — the UI default) or exact (exact phrase).
advertisersstring[]Pages to fetch: page URL, handle (Zalando), or numeric page ID. Handles/URLs are resolved to page IDs; unresolvable entries are reported in SUMMARY, not fatal.
adLibraryUrlsstring[]Pasted Ad Library search URLs. Every filter in the URL is parsed; explicit form fields override URL params.
adIdsstring[]Ad Library IDs for single-ad lookup.
countriesstring[]ISO-2 codes or ALL. Each term/advertiser is queried once per country.
activeStatusenumactive, inactive, or all.
adTypeenumall, or a regulated category: political_and_issue_ads, housing_ads, employment_ads, credit_ads, financial_products_and_services_ads.
mediaTypeenumall, image, video, meme, none.
platformsstring[]Subset of facebook, instagram, messenger, audience_network, threads.
languagesstring[]ISO-2 content languages.
startDateFrom / startDateTodateFilter by ad start date. Meta applies this approximately (see FAQ).
maxAdsPerQueryintUnique ads per query (default 100).
maxAdsTotalintHard cap for the whole run.
includeDetailsboolFetch EU transparency + advertiser enrichment (default true).
monitorobject{ enabled, monitorId, outputOnlyChanges }. See Monitor mode.
downloadMediaenumnone, images, images_and_videos — store creatives in the key-value store.
maxMediaSizeMbintSkip media files larger than this (default 50).
resolveLandingPagesboolFollow each ad's link through redirects; record the final URL and domain.
proxyConfigurationobjectApify Proxy by default.

Example inputs

Scrape Facebook & Instagram ads by keyword in two countries:

{ "searchTerms": ["running shoes"], "countries": ["US", "DE"], "maxAdsPerQuery": 200 }

Scrape all of a competitor's ads with EU transparency:

{ "advertisers": ["https://www.facebook.com/Zalando"], "countries": ["DE"], "includeDetails": true }

Paste a filtered Ad Library URL:

{ "adLibraryUrls": ["https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=sale&search_type=keyword_unordered&media_type=video"] }

Output

One dataset item per unique ad. Keys are always present in the same order; unavailable values are null, never omitted. schemaVersion is 1.0.

Output sample (trimmed, real)

{
"schemaVersion": "1.0",
"adArchiveId": "2244115343095346",
"adLibraryUrl": "https://www.facebook.com/ads/library/?id=2244115343095346",
"pageName": "Zalando",
"pageId": "365604620536",
"instagramUsername": "zalando",
"instagramFollowers": 3460695,
"pageVerification": "BLUE_VERIFIED",
"isActive": true,
"startDate": "2026-09-30T07:00:00.000Z",
"endDate": null,
"daysActive": 27,
"publisherPlatforms": ["FACEBOOK", "INSTAGRAM"],
"displayFormat": "VIDEO",
"bodyText": "Entdecke die neue Kollektion …",
"ctaText": "Jetzt shoppen",
"linkUrl": "https://www.zalando.de/...",
"landingDomain": "zalando.de",
"euTotalReach": 2704876,
"targetLocations": [{ "name": "Germany", "type": "countries", "excluded": false }],
"targetAges": { "min": 18, "max": 65 },
"targetGender": "All",
"payer": "Zalando SE",
"beneficiary": "Zalando SE",
"detailsStatus": "ok",
"query": "zalando",
"queryType": "search",
"scrapedAt": "2026-10-27T00:00:06.071Z"
}

Field reference (groups)

  • Identity — adArchiveId, collationId, collationCount, adLibraryUrl, schemaVersion
  • Advertiser — pageId, pageName, pageUrl, pageProfilePicUrl, pageLikeCount, pageCategories, pageVerification, instagramUsername, instagramFollowers, byline, disclaimer
  • Status & dates — isActive, startDate, endDate, daysActive, totalActiveTime
  • Placement — publisherPlatforms, searchCountry, targetedOrReachedCountries
  • Creative — displayFormat, bodyText, title, linkDescription, caption, ctaText, ctaType, linkUrl, landingUrl, landingDomain, utm, images, videos, cards, extraTexts, containsDigitallyCreatedMedia, containsSensitiveContent
  • Political/issue — isPoliticalAd, gatedType, spend, impressions, demographicDistribution, regionDistribution
  • EU DSA transparency — euTotalReach, reachByCountryAgeGender, targetLocations, targetAges, targetGender, payer, beneficiary, isAdTakenDown, detailsStatus
  • Derived — creativeHash, variantGroupId, mediaStoreKeys
  • Monitor — changeType, firstSeenAt, lastSeenAt
  • Run context — query, queryType, scrapedAt

detailsStatus explains every EU/detail null: ok (data present), not_in_eu (ad doesn't target the EU), not_published (taken down / no transparency record), failed (detail fetch errored — the list row is still delivered), skipped (includeDetails was off).

Dataset views

overview (key columns incl. euTotalReach and detailsStatus), creatives, euTransparency, monitor, and full.

SUMMARY record

Written to the key-value store. Per query: metaReportedCount (Meta's own result count), delivered, duplicatesSkipped, splitsUsed, coveragePct, pagesFetched, retries, blocks, durationSec, plus run totals, charged events, and any unresolved advertisers. Use coveragePct to confirm a run is complete.

How much does it cost to scrape Facebook ads?

This Actor is pay-per-event, so you pay for results, not run time:

EventPriceWhen
Actor start$0.005Once per run
Ad scraped$0.70 / 1,000Per unique ad delivered (EU details included)
Media stored$0.50 / 1,000Per creative file saved (only with downloadMedia)
Landing page resolved$0.20 / 1,000Per resolved URL (only with resolveLandingPages)

You are charged only for unique ads actually delivered — never for duplicates, failed rows, monitor "stopped" markers, or ads dropped by outputOnlyChanges.

Worked examples:

  • 1,000 ads with EU details, no media: ~$0.005 + $0.70 = $0.71.
  • 5,000 ads, images downloaded (~4 files/ad), no landing: ~$0.005 + $3.50 + ($0.50 × 20) = $13.51.
  • Daily monitor of one advertiser returning ~20 new ads/day: $0.005 + $0.014 = **$0.02/day**.

Monitor mode: track a competitor's ads over time

Meta's Ad Library has no export and no change history. Monitor mode adds both. State is kept in a named key-value store per monitorId.

{
"advertisers": ["Nike", "Adidas"],
"countries": ["US"],
"monitor": { "enabled": true, "monitorId": "sportswear-watch", "outputOnlyChanges": true }
}

Each run classifies every ad as new, continuing, or stopped (previously active, now gone), with stable firstSeenAt/lastSeenAt. With outputOnlyChanges: true, only new and stopped ads are pushed. Keep maxAdsPerQuery stable across runs on the same monitorId so change detection stays accurate.

Recipe: In the Apify Console, create a Schedule (e.g. daily) for this Actor with your monitor input, then add a webhook on "run succeeded" to Slack, Make, n8n, or Google Sheets to be notified of changes. Point the webhook at the dataset's monitor view, filtered to changeType ≠ continuing.

API, Python & JavaScript

curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~meta-ad-library-intelligence/runs?token=APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchTerms":["nike"],"countries":["US"],"maxAdsPerQuery":100}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'APIFY_TOKEN' });
const run = await client.actor('YOUR_USERNAME/meta-ad-library-intelligence').call({
searchTerms: ['nike'], countries: ['US'], includeDetails: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClient
client = ApifyClient("APIFY_TOKEN")
run = client.actor("YOUR_USERNAME/meta-ad-library-intelligence").call(
run_input={"searchTerms": ["nike"], "countries": ["US"], "includeDetails": True}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["adArchiveId"], item["euTotalReach"])

Use it from AI agents (Apify MCP)

The Actor is exposed through the Apify MCP server. Its versioned field contract and output schema let an agent call it and consume results without scraping-specific glue. Point your MCP client at https://mcp.apify.com, authorize, and call this Actor by name.

How it compares to other Facebook Ad Library scrapers

This ActorTypical alternatives
EngineHTTP-only, no browser in the hot pathOften browser-based (2 GB+ memory)
EU DSA transparencyIn every row, with detailsStatusHidden behind a separate view, or missing
Coverage reportingmetaReportedCount vs delivered, per queryRarely reported
Monitor modeBuilt in (new/stopped/continuing)Usually absent
MemoryRuns at 256–512 MBOften needs 1–2 GB

Facts about other Actors change; check their listings for current details.

FAQ

How do I scrape the Facebook Ad Library?

Enter a search term or a Facebook page, pick your countries, and run the Actor. It calls the public Ad Library the same way the website does and returns structured rows — no login and no Meta API token.

Is there a Meta / Facebook Ad Library API?

Meta's official Ad Library API is limited (mainly political/issue ads, with access approval). This Actor is an API alternative that covers all advertisers and exposes the data as a clean JSON dataset you can call from the Apify API, Python, JavaScript, or an AI agent.

Do I need to log in or provide a Facebook account?

No. Only public, logged-out data is read. No account, cookies, or access tokens.

Can I track a competitor's Facebook and Instagram ads over time?

Yes — use monitor mode. Schedule the Actor and each run reports which ads are new, which stopped, and how long each has been running.

The Ad Library is public data Meta publishes for transparency. Output may contain advertisers' personal data (e.g. payer names); GDPR and other compliance obligations are the user's responsibility.

Why is a field null?

Fields map to null when Meta doesn't expose them. For EU/detail fields, read detailsStatus.

Why is EU reach missing on US ads?

EU DSA transparency exists only for ads targeting the EU. detailsStatus will be not_in_eu.

Why don't my media URLs work later?

Meta's CDN URLs expire after a few days. Use downloadMedia to persist creatives in the key-value store.

My date filter looks approximate.

Meta applies the start-date filter loosely in the public Ad Library; the Actor sends exactly what the UI sends. Filter precisely downstream on startDate if you need a hard cutoff.

A page handle wasn't resolved.

Meta's page typeahead is login-gated. Supply the numeric page ID or a page URL for guaranteed resolution; unresolved handles are listed in SUMMARY.

Changelog

See CHANGELOG.md.