Meta Ad Library Scraper — Facebook & Instagram Ads API No Login avatar

Meta Ad Library Scraper — Facebook & Instagram Ads API No Login

Pricing

Pay per usage

Go to Apify Store
Meta Ad Library Scraper — Facebook & Instagram Ads API No Login

Meta Ad Library Scraper — Facebook & Instagram Ads API No Login

Bulk Meta Ad Library scraper — every Facebook & Instagram ad, creative, landing URL. $0.0015/ad. No login, no Graph API approval. Raw JSON passthrough. Perfect for creative and competitor research.

Pricing

Pay per usage

Rating

5.0

(1)

Developer

AffiliateScope

AffiliateScope

Maintained by Community

Actor stats

1

Bookmarked

8

Total users

5

Monthly active users

8 days ago

Last modified

Share

Meta Ad Library Scraper

Turn Meta's Ad Library into clean, structured JSON — every ad, every creative, every landing URL from Facebook, Instagram, Messenger, and Audience Network.

Paste any Ad Library URL, or search by keyword or Facebook Page ID. No login. No Meta developer account. No setup. Pay $0.05 per run + $0.0015 per ad.

Built on pure HTTP against Meta's internal GraphQL — no browser to crash, no DOM-scraping to maintain. Designed for scheduled scraping, agency workflows, and competitive ad intelligence at scale.


Quick start

From the Apify Console:

  1. Click Try for free at the top
  2. In the input form, pick one:
    • Paste Ad Library URLs (Option A), or
    • Type search queries + countries (Option B)
  3. Click Start. Watch results stream into the dataset.

From the API (curl):

curl -X POST 'https://api.apify.com/v2/acts/affiliatescope~meta-ads-scraper/runs?token=YOUR_APIFY_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"searchQueries": ["nike"],
"countries": ["US"],
"maxAdsPerSource": 500
}'

Results land in the run's default dataset within seconds of the first page. Stream them via the /dataset/items endpoint or export as CSV, JSON, JSONL, or XLSX from the UI.


What you get per ad

  • ad_archive_id + direct Library URL (inside __metadata.adLibraryUrl — derived from the ad ID)
  • Advertiser: Page name, ID, profile picture URL, categories, like count, profile URI
  • Full creative text: body, title, caption, link description, byline
  • Images: original + resized URLs, all creative variants (single, carousel, multi-card)
  • Videos: HD + SD URLs, preview image
  • CTA: button text + semantic type (Shop Now, Learn More, Download…)
  • Landing URL with tracking parameters preserved — affiliate tags, UTMs, campaign IDs intact
  • Delivery window: start/end dates, currently-active flag
  • Publisher mix: Facebook, Instagram, Messenger, Audience Network
  • Reach + spend: reach estimates, currency, spend bands (where Meta exposes them)
  • Political/issue ads: impressions, demographic breakdown, disclaimer label
  • __metadata: run context (query, country, page number, scrape timestamp, ordering index)

Full raw Meta response passes through untouched — when Meta adds new fields, you get them automatically without waiting for a scraper update.


Sample output (1 real record, trimmed)

Every record mirrors Meta's raw response shape — we don't normalize, rename, or drop fields. A __metadata sidecar at the top level carries the scrape context.

{
"ad_archive_id": "638485615120135",
"ad_id": null,
"page_id": "15087023444",
"page_name": "Nike",
"is_active": false,
"start_date": 1699430400,
"end_date": 1745650800,
"publisher_platform": ["FACEBOOK", "INSTAGRAM", "AUDIENCE_NETWORK", "MESSENGER"],
"currency": "",
"spend": null,
"impressions_with_index": { "impressions_text": null, "impressions_index": -1 },
"reach_estimate": null,
"categories": ["UNKNOWN"],
"contains_digital_created_media": false,
"contains_sensitive_content": false,
"targeted_or_reached_countries": [],
"snapshot": {
"body": {
"text": "Encuentra tu mejor estilo. Llegó el momento de que tu siguiente favorito sea el tuyo..."
},
"cta_text": "Install now",
"cta_type": "INSTALL_MOBILE_APP",
"link_url": "http://play.google.com/store/apps/details?id=com.nike.omega&...",
"caption": "play.google.com",
"title": "{{product.name}}",
"link_description": null,
"page_categories": ["Sportswear", "Product/service"],
"page_profile_picture_url": "https://scontent.xx.fbcdn.net/v/t39.35426-6/...",
"page_profile_uri": "https://www.facebook.com/nike",
"page_like_count": 39643468,
"cards": [
{ "body": "Encuentra tu mejor estilo...", "original_image_url": "https://scontent.xx.fbcdn.net/..." }
],
"videos": [],
"images": [],
"display_format": "DCO"
},
"__metadata": {
"order": 1,
"sourceOrder": 1,
"page": 1,
"sourceKey": "kw:US:nike",
"sourceType": "keyword",
"query": "nike",
"country": "US",
"adLibraryUrl": "https://www.facebook.com/ads/library/?id=638485615120135",
"scrapedAt": "2026-04-19T13:28:01.053Z"
}
}

Notes on field population:

  • spend, currency, reach_estimate, impressions_with_index.impressions_text only populate for political and social-issue ads (where Meta's DSA disclosure rules require it). Most commercial ads have empty/null values in these fields — this is Meta's choice, not a scraper limitation.
  • cards[] contains one entry per creative variant (single image ads have 1 card; carousels have multiple). Each card has its own body text, image URLs, and optional video URLs.
  • snapshot.videos / snapshot.images are set for single-creative ads; multi-creative ads carry media inside snapshot.cards[].*_image_url / *_video_url instead.
  • Raw passthrough means you also receive fields not shown above: ad_id, collation_count, collation_id, gated_type, state_media_run_label, regional_regulation_data, and more — everything Meta sends, you get.

Inputs

Provide one of these four source types, plus optional filters.

SourceWhat it does
Ad Library URLsPaste any URL from facebook.com/ads/library — filters baked into the URL are used
Search queriesFree-text keyword search, one per line, scoped by country
Page IDsNumeric Facebook Page IDs — returns every ad from those Pages
Ad IDsSpecific ad_archive_id values for single-ad lookups (v2.1)

Filters (apply to Query Builder sources, not pasted URLs):

  • Countries: ISO-3166 alpha-2 (US, GB, DE…) or ['ALL'] for worldwide
  • Active status: currently-running / stopped / both
  • Ad category: all / political & social-issue / housing / employment / credit
  • Media type: image / video / carousel / meme / text-only
  • Publisher platforms: any subset of FB / IG / Messenger / Audience Network
  • Content languages: ISO-639 codes
  • Date range: from and to in YYYY-MM-DD
  • Sort: total impressions (default) / most recent first

See the Input tab for the full schema — every field is documented with an example.


Pricing

Pay only for what you scrape. No monthly minimums, no subscriptions, no commitments.

EventPrice
Actor run start$0.05
Each ad scraped$0.0015

Worked examples:

Use caseRun sizeCost
Testing the output before deciding50 ads$0.13
Weekly creative review for 1 brand500 ads$0.80
Competitive intel across 5 brands5,000 ads$7.55
Agency monthly refresh, 30 brands30,000 ads$45.05
Trend dataset across 50 countries100,000 ads$150.05

Set a maxTotalChargeUsd limit in the run config and the scraper will honor it — automatic budget cap, no surprise bills.


Why this scraper

AlternativeWhy this scraper wins
Meta's Graph API (ads_archive)No Business Manager approval needed. All ad types accessible, including commercial ads. Full creative fields (Graph API restricts most of them to political/issue ads).
Playwright-based scrapers3× cheaper per ad. No DOM dependency — doesn't break when Meta changes their frontend.
DIY from scratchZero setup, zero maintenance. Auto-rotates when Meta changes their internal query IDs.
Manual Ad Library browsingStructured JSON at scale, scheduled refresh, one-click CSV / JSON / XLSX export.

How it works

  • Pure HTTP against Meta's GraphQL — no browser, no Chromium, no Puppeteer/Playwright. Significantly lower compute cost per ad than browser-based scrapers.
  • Sticky residential sessions — one session bootstraps once, then paginates through thousands of ads on the same sticky IP. Drastically reduces the per-run handshake overhead that trips up naive scrapers.
  • Full Meta response passthrough — output is raw JSON from Meta with a __metadata sidecar (query, country, page, order, timestamp). You get every field Meta exposes, not a lossy normalized subset.

Reliability

Built for sustained scheduled workloads. Typical throughput on Apify residential proxy is ~100 ads per minute per source, so a 1,000-ad single-keyword run finishes in about 10 minutes. Multi-source runs (several keywords or Page IDs together) parallelize — 10 concurrent sources triple to quadruple the effective rate. Recent production runs have completed 290+ pages with zero failed requests.


Performance tuning

Two knobs shape how fast your run completes and how much memory it needs.

Memory (memoryMbytes)

Default is 512 MB — enough for up to ~10 concurrent sources. Bump it in the Apify Console's Memory dropdown when you need more:

WorkloadRecommended memory
1–10 sources (URLs, keywords, or Page IDs)512 MB (default)
10–40 sources concurrent1 GB
40+ sources concurrent2 GB
Single massive scrape with maxAdsPerSource: 100,000+1 GB

Memory is fixed at run start — Apify doesn't auto-scale mid-run. Allocating more than you need doesn't make the run faster; it just increases compute cost (you're billed per memoryGB × runtime). Allocating less than you need causes OOM and an aborted run. The defaults are sized for the typical scheduled-scrape workflow.

Concurrency (maxConcurrency)

Default is 3. This controls how many sources (URLs, keywords, Page IDs) run in parallel. Important mental model:

  • Between sources: fully parallel. 10 keywords with maxConcurrency: 10 all scrape simultaneously.
  • Within one source: strictly serial. Meta's pagination cursor for page 2 comes from page 1's response, so one source pages one at a time regardless of concurrency.

The scraper automatically caps effective concurrency at the number of sources you provide. If you set maxConcurrency: 20 but pass only 1 search query, effective concurrency = 1 — the other 19 slots would sit idle and churn session bootstraps. The config panel at run start prints the effective value (e.g. concurrency 1 (capped from 20: only 1 source)).

Practical guide:

You haveSet maxConcurrency to
1 URL / 1 keyword / 1 Page ID1
2–5 sources= number of sources
5–20 sources5 (balance throughput vs proxy-pool usage)
20+ sources, time-sensitive10 (then bump memory to 1 GB)

A 10,000-ad single-keyword run at concurrency: 1 finishes in ~100 minutes. Split into 10 keywords × 1,000 ads each with concurrency: 10 and the same 10,000 ads finish in ~10 minutes — roughly 10× faster because all 10 sources scrape simultaneously.


Integration

  • Schedule runs from the Apify Console (hourly, daily, weekly, cron)
  • Webhooks on run completion — Zapier, Make, n8n, Slack, or your own backend
  • Dataset API — pull results as CSV, JSON, JSONL, or XLSX, or stream via HTTP
  • Automatic charge cap — set maxTotalChargeUsd per run, scraper stops cleanly when budget is reached
  • Data-pipeline ready — push datasets to BigQuery / Snowflake / S3 via Apify's one-click integrations

FAQ

Is this legal? Yes. The Meta Ad Library is a public transparency tool operated by Meta — the same data a human can browse at facebook.com/ads/library. We scrape only data Meta has explicitly published to this tool. No login, no personal data, no private targeting details. Residential proxies obey Meta's IP-level rate limits; sessions retire and rotate cleanly when Meta signals throttling.

How fresh is the data? Real-time. Each run fetches directly from Meta's live endpoint — no caching, no intermediate storage. An ad published 5 seconds before your run will appear in the results if Meta's Ad Library has indexed it.

Will it break when Meta changes their Ad Library? Unlikely. We don't scrape the DOM — we use Meta's own internal GraphQL API, which is the same pipeline Meta's own Ad Library frontend uses. When Meta deploys a backend change, the scraper auto-detects the rotation and continues working on the next request. If a change does require a manual update, we prioritize and ship it as quickly as possible.

What about rate limits? Handled transparently. The scraper uses Apify's residential proxy pool (default setting) — each Crawlee session gets a sticky residential IP. On rate-limit errors, the session retires and a fresh IP picks up where the last one left off. You won't see failed requests in normal operation.

Compared to Meta's Graph API? Meta's Graph API ads_archive endpoint gates most fields behind political/issue-ads approval, which requires Business Manager verification and takes weeks to obtain. This scraper returns every ad type Meta publishes to the Library, including commercial ads with full creative text and images — no approval required.

GDPR / privacy compliance? The Ad Library publishes no PII. All personal targeting details are aggregated before Meta exposes them. The only identifiers in the output are Page IDs (corporate advertiser entities) and ad archive IDs. Spend/impression data is bucket-aggregated, not per-user.

What if I need data you don't currently extract? Because we pass through Meta's raw response, every field Meta returns is in the dataset — even fields we don't explicitly document. Use dataset.items[0] to inspect the full shape. If a field is missing because Meta didn't include it for that ad, it's genuinely not available.

Can I run this continuously? Yes. Set up a scheduled run in the Apify Console (daily, hourly, cron) and results stream into a rotating dataset. Combined with a maxTotalChargeUsd budget cap, you get subscription-like monthly spend predictability with per-ad billing.

How do I export the data? The Apify Console offers one-click export as CSV, JSON, JSONL, or XLSX. Programmatically, fetch /v2/datasets/{id}/items to stream records. For data-warehouse integrations, use Apify's built-in push integrations to BigQuery, Snowflake, or S3.


Support

Contact the actor owner (affiliatescope) via the Apify Console. We respond within one business day on weekdays. Confirmed scraper failures are triaged the same day.


Keywords

Facebook Ads scraper, Meta Ad Library API, Instagram Ads scraper, ad intelligence, competitor ad research, political ad transparency, EU DSA ads dataset, ad spy tool, creative research, Facebook advertising API alternative, ad library export, competitor creative monitoring, affiliate marketing intelligence.