# Facebook Ad Library Scraper — Facebook & Instagram Ads (`scrapeify/meta-ad-library-scraper`) Actor

Facebook Ad Library scraper for Meta ads. Extract Facebook and Instagram ads by keyword, Page ID, or URL. Sort by impressions or most recent. Get creatives, CTAs, and spend estimates in 100+ languages. No cookies or API key.

- **URL**: https://apify.com/scrapeify/meta-ad-library-scraper.md
- **Developed by:** [Scrapeify](https://apify.com/scrapeify) (community)
- **Categories:** Social media, Developer tools, AI
- **Stats:** 74 total users, 9 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $8.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Facebook Ad Library Scraper — Facebook & Instagram Ads

**Facebook Ad Library scraper** and **Meta Ad Library scraper**. Extract **Facebook and Instagram ads** by keyword, Page ID, or Ad Library URL. Sort by impressions or most recent, paginate Meta's GraphQL API, and get one Dataset row per ad with creatives, CTAs, spend/impression estimates, timing, distribution, and status. No cookies or API key required.

Supports **100+ languages** including Arabic, Chinese, Japanese, Korean, and Russian. Built for competitive intelligence, political research, creative strategy, and AI pipelines.

***

### Features

| Capability | Detail |
|---|---|
| **Three seed modes** | `keyword` (brand/topic search), numeric `pageId`, or full `adLibraryUrl` |
| **Sort options** | `total_impressions` (high to low) or `most_recent` (relevancy monthly grouped) |
| **No cookies required** | Uses Meta's public GraphQL API without authentication |
| **Unlimited results** | No hard cap — paginate until `maxResults` or exhaustion |
| **Full nested schema** | `metadata`, `ad_content`, `timing`, `performance`, `distribution`, `status`, `additional_info` |
| **100+ language support** | Universal language handling for global ad research |
| **Proxy support** | Configurable via `PROXY_URL` environment variable |
| **300-second watchdog** | Scrape timeout with typed error objects |
| **Run summary** | Aggregated spend, impressions, platforms, timing in `OUTPUT.summary` |
| **Schema documentation** | `OUTPUT.data.schema` for field-group documentation and codegen |
| **URL flexibility** | Accepts both `facebook.com/ads/library` and `meta.com/ads/library` URLs |

***

### Use Cases

#### Competitive Creative Intelligence

Pull all active and archived ads for any brand or category keyword. Analyze creative formats (carousel, video, single image), CTA patterns, offer types, and messaging angles. Track competitor creative refreshes and campaign launches by monitoring new `ad_archive_id` values.

#### Political & Issue Ad Monitoring

Research political advertising transparently. Filter by country, date range, and status within custom `adLibraryUrl` inputs. Analyze spend patterns, platform distribution, and targeted country reach for political campaigns.

#### E-Commerce & DTC Brand Research

Track direct-to-consumer creative strategies at scale. Identify which product-led formats, promotional structures, and urgency CTAs dominate high-spend categories across Facebook, Instagram, and Messenger.

#### Spend Intelligence & Media Planning

Pull impression-weighted ad rankings using `sortBy: total_impressions`. Identify which brands are investing most heavily in your category. Build directional spend benchmarks from Meta's publicly disclosed transparency estimates.

#### AI Creative Analysis

Feed structured `ad_content.body` and `title` fields into LLM classifiers to cluster themes, score messaging quality, detect prohibited claims, categorize offer types, and generate creative briefs at scale.

#### Automated Competitive Monitoring

Schedule nightly runs for tracked brands and keywords. Alert on new campaign launches, budget increases, or creative pivots using `ad_archive_id` diff logic.

#### RAG & Knowledge Base Construction

Index ad creative text with temporal metadata in vector databases. Enable queries like "what messaging did Brand X use for summer promotions?" using semantic retrieval with timestamped ad records.

#### Market Research & Category Analysis

Map advertiser landscape for any keyword — who is advertising, at what volume, on which platforms, and with what creative approaches. Export for BI analysis, client reporting, and strategy briefings.

***

### Why Choose This Actor

- **No cookies, no credentials** — direct GraphQL API access to Meta's public transparency data
- **Flexible seeds** — keyword OSINT, known Page ID dossiers, and custom URL presets in one actor
- **Impression-ranked results** — sort by `total_impressions` for spend-weighted competitive analysis
- **Universal language support** — 100+ languages for global ad research workflows
- **Production schema** — `OUTPUT.data.schema` documents field families for TypeScript/Python codegen
- **Consistent envelope** — identical nested structure as Scrapeify Instagram and WhatsApp actors for unified warehousing

***

### Quick Start

1. Open the Scrapeify **Meta Ad Scraper** on Apify Console.
2. Choose exactly one seed: enter a **`keyword`**, a numeric **`pageId`**, or paste a full **`adLibraryUrl`**.
3. Set **`maxResults`** (start with 50 to validate filters).
4. Optionally set **`sortBy`** (`total_impressions` for spend-weighted ranking, `most_recent` for freshness).
5. After completion: export **Dataset** as JSONL, or read **`OUTPUT.summary`** for aggregates.

> **Tip:** To find a brand's numeric Page ID, use the [Scrapeify Brand Finder](https://apify.com/scrapeify/facebook-page-id-finder) actor first.

***

### Input Schema

```json
{
  "keyword": "nike",
  "maxResults": 120,
  "sortBy": "total_impressions"
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| `keyword` | string | One-of | Brand name or topic search (e.g. `nike`, `fintech app`). Default: `nike`. |
| `pageId` | string | One-of | Numeric Facebook Page ID. Use Brand Finder to resolve from brand name. |
| `adLibraryUrl` | string | One-of | Full Ad Library URL. Must contain `facebook.com/ads/library` or `meta.com/ads/library`. |
| `maxResults` | integer | Yes | Ads to collect. Minimum 1. No hard upper limit — paginate to exhaustion. Default: 50. |
| `sortBy` | enum | No | `total_impressions` (default) or `most_recent`. |

**Exactly one** of `keyword`, `pageId`, or `adLibraryUrl` should be active per run.

***

### Output Schema

#### Dataset Row (one row per ad)

```json
{
  "metadata": {
    "scraped_at": "2026-05-07T04:00:00.000Z",
    "ad_archive_id": "123456789012345",
    "ad_id": "987654321",
    "page_id": "1234567890",
    "page_name": "Example Brand",
    "page_like_count": 2400000,
    "page_profile_uri": "https://www.facebook.com/examplebrand",
    "page_categories": ["Retail", "Shopping & Retail"]
  },
  "ad_content": {
    "body": "Summer sale — 40% off sitewide. Free shipping on orders over $50.",
    "title": "Shop the Summer Sale",
    "link_url": "https://www.example.com/summer-sale",
    "link_description": "Ends July 31.",
    "cta_text": "Shop Now",
    "cta_type": "SHOP_NOW",
    "cards": [],
    "images": ["https://scontent.xx.fbcdn.net/v/t45.1600-4/..."],
    "videos": []
  },
  "timing": {
    "start_date": "2026-05-01",
    "end_date": null,
    "total_active_time": null
  },
  "performance": {
    "spend": 50000,
    "currency": "USD",
    "impressions": 3100000,
    "impressions_index": 85,
    "reach_estimate": null
  },
  "distribution": {
    "publisher_platform": ["FACEBOOK", "INSTAGRAM"],
    "targeted_or_reached_countries": ["US", "CA", "GB", "AU"],
    "political_countries": []
  },
  "status": {
    "is_active": true,
    "is_aaa_eligible": false,
    "is_reshared": false,
    "has_user_reported": false,
    "contains_sensitive_content": false
  },
  "additional_info": {
    "categories": [],
    "archive_types": [],
    "collation_count": 1,
    "collation_id": null,
    "display_format": "IMAGE"
  }
}
```

#### Run Summary (`OUTPUT` key in default KV store)

```json
{
  "summary": {
    "totalAds": 120,
    "searchType": "keyword_unordered",
    "identifier": "nike",
    "adLibraryUrl": "https://www.facebook.com/ads/library/?country=ALL&q=nike&search_type=keyword_unordered&sort_data[mode]=total_impressions",
    "sortBy": "total_impressions",
    "keyword": "nike",
    "pageId": null,
    "urlParams": {
      "country": "ALL",
      "ad_type": "all",
      "active_status": "all"
    },
    "totalSpend": 125000.50,
    "totalImpressions": 9800000,
    "uniquePlatforms": ["FACEBOOK", "INSTAGRAM", "MESSENGER"],
    "scrapedAt": "2026-05-07T04:00:00.000Z",
    "pagesScraped": 14,
    "executionTimeSeconds": 42.3,
    "status": "SUCCESS",
    "error": null
  },
  "data": {
    "ads": ["...array of full ad objects..."],
    "schema": {
      "metadata": ["scraped_at", "ad_archive_id", "ad_id", "page_id", "page_name", "page_like_count", "page_profile_uri", "page_categories"],
      "ad_content": ["body", "title", "link_url", "link_description", "cta_text", "cta_type", "cards", "images", "videos"],
      "timing": ["start_date", "end_date", "total_active_time"],
      "performance": ["spend", "currency", "impressions", "impressions_index", "reach_estimate"],
      "distribution": ["publisher_platform", "targeted_or_reached_countries", "political_countries"],
      "status": ["is_active", "is_aaa_eligible", "is_reshared", "has_user_reported", "contains_sensitive_content"],
      "additional_info": ["categories", "archive_types", "collation_count", "collation_id", "display_format"]
    }
  }
}
```

| Field | Type | Description |
|---|---|---|
| `summary.totalAds` | integer | Total ads collected in this run |
| `summary.searchType` | string | `keyword_unordered`, `page`, or `url_based` |
| `summary.totalSpend` | number | Sum of spend estimates (mixed currencies possible) |
| `summary.totalImpressions` | number | Sum of impression estimates |
| `summary.uniquePlatforms` | array | Distinct publisher platforms in collected ads |
| `summary.pagesScraped` | integer | GraphQL pagination pages fetched |
| `summary.executionTimeSeconds` | number | Total scrape duration |
| `summary.status` | string | `SUCCESS`, `ERROR`, `NO_RESULTS`, or `TIMEOUT` |
| `summary.error` | object/null | Typed error: `type`, `message`, `details`, `suggestion` |
| `data.schema` | object | Field group documentation for codegen and schema drift detection |

***

### API Examples

#### cURL

```bash
curl "https://api.apify.com/v2/acts/scrapeify~meta-facebook-ad-scrapper-using-ad-library-url-premium/runs?token=$APIFY_TOKEN" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "pageId": "15087023444",
    "maxResults": 80,
    "sortBy": "most_recent"
  }'
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

## Search by keyword
run = client.actor("scrapeify/meta-ad-library-scraper").call(
    run_input={"keyword": "fintech app", "maxResults": 200, "sortBy": "total_impressions"}
)

## Or by Page ID
run = client.actor("scrapeify/meta-ad-library-scraper").call(
    run_input={"pageId": "15087023444", "maxResults": 400}
)

for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(ad["ad_content"]["body"], ad["performance"].get("impressions"))
```

#### JavaScript / Node.js

```javascript
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

// Search by full Ad Library URL (with custom geo/date filters)
const run = await client.actor("scrapeify/meta-ad-library-scraper").call({
  adLibraryUrl: "https://www.facebook.com/ads/library/?country=ALL&q=travel&search_type=keyword_unordered",
  maxResults: 150,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Collected ${items.length} ads across ${new Set(items.flatMap(a => a.distribution?.publisher_platform || [])).size} platforms`);
```

***

### Integration Examples

#### ChatGPT / Custom GPT Actions

Register the Apify run endpoint as a Custom GPT action. Return structured ad JSON — body, title, spend, impressions, platforms — for the model to analyze creative strategies, summarize competitor messaging, or build category benchmark tables.

#### Claude Tool Use

```python
@tool
def search_meta_ads(keyword: str, max_results: int = 100, sort_by: str = "total_impressions") -> list:
    """Search Meta Ad Library for ad creatives by keyword. Returns structured ad data."""
    run = client.actor("scrapeify/meta-ad-library-scraper").call(
        run_input={"keyword": keyword, "maxResults": max_results, "sortBy": sort_by}
    )
    return client.dataset(run["defaultDatasetId"]).list_items().items
```

#### Gemini

Pass 500+ ad `body` + `title` pairs into Gemini's long-context window for thematic clustering, category labeling, and messaging trend identification at scale.

#### LangChain

```python
from langchain.tools import tool

@tool
def get_competitor_ads(brand_name: str, max_ads: int = 200) -> list:
    """Retrieve Meta Ad Library creatives for a brand. Sorted by total impressions."""
    run = client.actor("scrapeify/meta-ad-library-scraper").call(
        run_input={"keyword": brand_name, "maxResults": max_ads, "sortBy": "total_impressions"}
    )
    return client.dataset(run["defaultDatasetId"]).list_items().items
```

Chain: `search_meta_ads` → `analyze_creative_themes` → `generate_brief`

#### CrewAI

```python
## BrandResearchAgent: resolves Page IDs using Brand Finder
## AdAnalystAgent: pulls creatives using Meta Ad Scraper
## CreativeStrategistAgent: generates briefs from structured ad data
## ComplianceAgent: flags potential policy violations in ad copy
```

#### AutoGen

Multi-agent workflow: `UserProxyAgent` specifies competitive research scope; `DataAgent` pulls ad creative data; `AnalysisAgent` clusters by theme; `ReportAgent` summarizes with spend-weighted ranking.

#### n8n / Make.com / Zapier

Cron trigger → Apify run → compare new `ad_archive_id` values against last run → push new ad launches to Slack or email alert.

#### RAG Systems

Chunk `ad_content.body` with metadata (`page_name`, `start_date`, `publisher_platform`, `impressions`). Index in Pinecone, Weaviate, or Qdrant. Enable queries like "what discount messaging do fitness brands use on Facebook?"

#### Vector Databases

Embed `body` + `title` as semantic vectors. Store `page_id`, `impressions`, `is_active`, `publisher_platform`, and `start_date` as filterable metadata for faceted creative research.

***

### Frequently Asked Questions

**1. Do I need cookies or a Facebook account?**
No. The actor uses Meta's public GraphQL API endpoint without any authentication.

**2. Can I use both `facebook.com` and `meta.com` Ad Library URLs?**
Yes — both URL patterns are accepted for the `adLibraryUrl` input.

**3. What is the difference between `sortBy` options?**
`total_impressions` ranks ads by estimated impression volume (high to low) — best for spend-weighted competitive analysis. `most_recent` uses Meta's relevancy monthly grouped view — better for tracking campaign freshness.

**4. How do I find a brand's numeric Page ID?**
Use the [Scrapeify Brand Finder](https://apify.com/scrapeify/facebook-page-id-finder) actor — enter the brand name and receive deduplicated Page ID candidates.

**5. Is there a maximum number of ads per run?**
No enforced cap — the actor paginates until `maxResults` is reached or the Ad Library returns no further results.

**6. Are spend and impressions figures exact?**
No — Meta's Ad Library publishes **transparency estimates**, not audited financial figures. Treat as directional signals.

**7. What is `NO_RESULTS` status?**
The Ad Library returned no matching ads for the given filter combination. Not a credential failure — try broadening the search keyword, country scope, or active status filter.

**8. How do I scrape Instagram-only ads?**
Use the dedicated [Instagram Ad Scraper](https://apify.com/scrapeify/instagram-ad-library-scraper) which enforces the Instagram platform filter at URL construction.

**9. What does `sortBy` ignored mean?**
Conflicting embedded `sort_data` in a pasted URL may conflict with the `sortBy` parameter. Inspect the final `adLibraryUrl` in `OUTPUT.summary` to verify sort propagation.

**10. How do I deduplicate across runs?**
Key on `metadata.ad_archive_id` — the stable unique identifier for each ad in the Meta Ad Library.

**11. Can I filter by country or date in the URL?**
Yes — encode geographic and date filters in a custom `adLibraryUrl` pasted from the browser's Ad Library address bar.

**12. Are carousel ads returned as one row or multiple?**
One Dataset row per ad. Carousel cards are nested in `ad_content.cards[]`.

**13. What does `display_format` contain?**
The ad creative format: `IMAGE`, `VIDEO`, `CAROUSEL`, `DPA`, etc. from `additional_info.display_format`.

**14. Does it support non-Latin brand names?**
Yes — 100+ languages supported including Arabic, Chinese, Japanese, Korean, and Russian. UTF-8 throughout.

**15. What causes `TIMEOUT` status?**
Very deep pagination for large `maxResults` may hit the 300-second watchdog. Reduce `maxResults` and rerun, or shard across multiple actors.

**16. Are inactive/archived ads included?**
Depends on URL parameters. Pass `active_status=all` in `adLibraryUrl` to include both active and archived creatives.

**17. Can I extract video creative URLs?**
Yes — `ad_content.videos[]` contains URLs when video assets are present. Fetching media is your responsibility.

**18. What does `collation_count` mean?**
Number of ad variations Meta groups under one creative ID. Usually 1 for individual ads; higher for A/B test variants.

**19. Is there a webhook for run completion?**
Yes — configure Apify webhooks on `RUN.SUCCEEDED` to automatically pull the Dataset after completion.

**20. How do I handle FX-heterogeneous spend aggregates?**
Check `performance.currency` per ad. Normalize to a common currency before summing spend across a dataset.

**21. Can I scrape political advertising?**
Yes — political ad data is available in Meta's transparency library. Observe legal and ethical obligations in your jurisdiction.

**22. What is `impressions_index`?**
A normalized impression index (0–100) from Meta's API. Useful for relative ranking when absolute numbers aren't available.

**23. How do I set up a nightly competitive monitoring pipeline?**
Schedule Apify runs → compare `ad_archive_id` sets against yesterday's run → route new IDs to Slack alerts → push full records to your data warehouse.

**24. Does the actor work for WhatsApp-specific ads?**
For WhatsApp CTA ads, use the dedicated [WhatsApp Ad Scraper](https://apify.com/scrapeify/whatsapp-ad-scraper) which enforces the WhatsApp platform filter.

**25. Are there data retention or compliance obligations?**
Meta's Ad Library terms of service apply. Verify data retention policies for your use case — especially for political ad data and PII in page names.

***

### Best Practices

- **Start with small `maxResults`** to validate geographic and media filters before scaling
- **Log `adLibraryUrl` from `OUTPUT.summary`** when debugging sort or filter behavior — inspect the final constructed URL
- **Use exponential backoff** at orchestration level on `TIMEOUT` errors
- **Store `OUTPUT` + Dataset IDs** together for reproducibility audits
- **Deduplicate on `ad_archive_id`** in your warehouse to prevent duplicate rows from overlapping runs
- **Archive `searchUrl` with each analytical snapshot** for reproducibility
- **Normalize currencies before aggregation** — `performance.currency` varies per ad row

***

### Performance & Scalability

| Factor | Guidance |
|---|---|
| **Throughput** | Pagination-bound; each GraphQL page returns ~25 ads |
| **Timeout risk** | Very large `maxResults` may hit 300s — shard by keyword or date range |
| **Horizontal scaling** | Multiple parallel actor runs per brand shard or geographic segment |
| **Memory** | Consistent JSON rows — predictable at any scale |
| **Large datasets** | Prefer Dataset export over KV-embedded arrays for runs returning 1000+ ads |

***

### AI & Automation Workflows

**Creative clustering pipeline:** Embed `body` + `title` → cluster by cosine similarity → label theme groups (discount, social proof, urgency, education, product) → generate category-level creative briefs.

**Spend intelligence:** Pull `total_impressions`-sorted ads for top 20 competitors → aggregate by `page_name` → build spend-proxy leaderboard → update BI dashboard weekly.

**Compliance screening:** Extract `ad_content.body` for all active ads in a regulated vertical → run policy-rule LLM classifier → flag potential violations → queue for legal review.

**Campaign launch detection:** Schedule daily runs → diff `ad_archive_id` sets → alert on new clusters of IDs indicating budget scaling or new campaign launches.

***

### Error Handling

| Scenario | Behavior |
|---|---|
| Multiple seeds active | Validation expects single coherent seed — leave others empty |
| Non-numeric `pageId` | Validation error with descriptive message |
| Invalid `adLibraryUrl` hostname | Validation error — must contain Ad Library domain |
| `NO_RESULTS` | Clean completion; `summary.status = NO_RESULTS`, not a failure |
| `TIMEOUT` | Reduce `maxResults`; check `pagesScraped` for progress |
| `SCRAPING_ERROR` | Typed error with `details` and `suggestion`; check proxy health |
| `DATA_STORAGE_ERROR` | Dataset write failure; partial results may be preserved |

Error types surfaced: `INVALID_INPUT`, `INVALID_URL`, `SCRAPING_ERROR`, `TIMEOUT`, `DATA_STORAGE_ERROR`, `UNKNOWN_ERROR` — each with `details` and `suggestion` strings.

***

### Trust & Reliability

Scrapeify operates this actor with explicit validation before network work, summary-first outputs for dashboards, and comprehensive schema documentation in `OUTPUT.data.schema` — designed for teams building production competitive intelligence and creative analytics pipelines.

***

### Related Scrapeify Actors

Explore the full Scrapeify suite — chain these actors together for end-to-end automation pipelines:

| Actor | What it does |
|---|---|
| [Amazon Scraper](https://apify.com/scrapeify/amazon-scraper) | ASINs, prices, sponsored flags across 23 marketplaces |
| [Instagram Ad Library Scraper](https://apify.com/scrapeify/instagram-ad-library-scraper) | Instagram-only ads from Meta Ad Library |
| [WhatsApp Ad Scraper](https://apify.com/scrapeify/whatsapp-ad-scraper) | Click-to-WhatsApp ad creatives |
| [YouTube Video Downloader](https://apify.com/scrapeify/youtube-video-downloader) | Videos & audio to Apify Key-Value Store |
| [Meta Brand & Page ID Finder](https://apify.com/scrapeify/facebook-page-id-finder) | Resolve brand names to numeric Page IDs |
| [Google Maps Scraper](https://apify.com/scrapeify/google-maps-scraper) | Local business leads, reviews, emails, contacts |
| [Google News Scraper](https://apify.com/scrapeify/google-news-scraper) | Headlines, sources, article URLs (up to 2K) |

***

*Meta and Facebook are trademarks of Meta Platforms, Inc. This actor is not affiliated with or endorsed by Meta.*

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "SoftwareApplication",
      "name": "Scrapeify Meta Ad Library Scraper",
      "applicationCategory": "DeveloperApplication",
      "applicationSubCategory": "Ad Intelligence API",
      "operatingSystem": "Cloud (Apify Platform)",
      "description": "Extract Facebook and Meta Ad Library transparency data programmatically. Search by keyword, Page ID, or full Ad Library URL. Sort by total impressions or most recent. Supports 100+ languages. No cookies or Meta API credentials required.",
      "url": "https://apify.com/scrapeify/meta-ad-library-scraper",
      "featureList": [
        "Three seed modes: keyword, Page ID, URL",
        "Sort by total_impressions or most_recent",
        "100+ language support including Arabic, Chinese, Japanese, Korean, Russian",
        "No authentication required",
        "Unlimited result count",
        "Full nested ad creative schema"
      ],
      "offers": {
        "@type": "Offer",
        "category": "SaaS"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Scrapeify"
      }
    },
    {
      "@type": "FAQPage",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "Do I need cookies or a Facebook account to use the Meta Ad Library Scraper?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "No. The actor uses Meta's public GraphQL API endpoint without any authentication."
          }
        },
        {
          "@type": "Question",
          "name": "What is the difference between sortBy options?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "total_impressions ranks ads by estimated impression volume, best for spend-weighted competitive analysis. most_recent uses Meta's relevancy monthly grouped view, better for tracking campaign freshness."
          }
        },
        {
          "@type": "Question",
          "name": "Is there a maximum number of ads per run?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "No enforced cap — the actor paginates until maxResults is reached or the Ad Library returns no further results."
          }
        },
        {
          "@type": "Question",
          "name": "How do I find a brand's numeric Page ID?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Use the Scrapeify Brand Finder actor — enter the brand name and receive deduplicated Page ID candidates with category, likes, and avatar."
          }
        },
        {
          "@type": "Question",
          "name": "Are spend and impressions figures exact?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "No. Meta's Ad Library publishes transparency estimates, not audited financial figures. Treat as directional signals only."
          }
        },
        {
          "@type": "Question",
          "name": "Can I scrape political advertising?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Yes — political ad data is available in Meta's transparency library. Observe legal and ethical obligations in your jurisdiction."
          }
        }
      ]
    }
  ]
}
</script>

***

Built by **[Scrapeify](https://apify.com/scrapeify)** on Apify.

Powered by **[AdScrape](https://www.adscrape.in/)**.

# Actor input Schema

## `keyword` (type: `string`):

Search term or brand (e.g. nike, adidas). Use this OR pageId OR adLibraryUrl — only one needed.

## `pageId` (type: `string`):

Numeric Facebook/Meta Page ID (brand ID). Use this OR keyword OR adLibraryUrl.

## `adLibraryUrl` (type: `string`):

Full Meta Ad Library URL with search parameters. Use this OR keyword OR pageId.

## `maxResults` (type: `integer`):

How many ads to collect. Paginates until this count or no more results. No upper limit.

## `sortBy` (type: `string`):

total\_impressions: highest impressions first. most\_recent: Meta relevancy/monthly grouped view.

## Actor input object example

```json
{
  "keyword": "nike",
  "adLibraryUrl": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=ALL&q=nike&search_type=keyword_unordered",
  "maxResults": 50,
  "sortBy": "total_impressions"
}
```

# Actor output Schema

## `ads` (type: `string`):

One JSON object per ad from Meta Ad Library.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapeify/meta-ad-library-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("scrapeify/meta-ad-library-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call scrapeify/meta-ad-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapeify/meta-ad-library-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/z2pwxA5rg3j0FpIcO/builds/qlpEgG7p1ZVGSwWln/openapi.json
