# Meta Ad Library Scraper - Facebook Ad Spy, No Login (`buff_pineapple/meta-ad-library-scraper`) Actor

Scrape Facebook & Instagram ads from the Meta Ad Library — no login, no API key. Get ad creatives (HD/SD video + images), copy, CTAs, landing pages, advertiser details & political ad spend, across all countries and filters. Pay per ad, no monthly fee.

- **URL**: https://apify.com/buff\_pineapple/meta-ad-library-scraper.md
- **Developed by:** [yossef Nagy](https://apify.com/buff_pineapple) (community)
- **Categories:** Marketing, Social media, E-commerce
- **Stats:** 14 total users, 4 monthly users, 98.4% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.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/actors/running/actors-in-store.md#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

## Meta Ad Library Scraper - Facebook Ad Spy, No Login

The **Meta Ad Library Scraper** (a.k.a. **Facebook Ad Library Scraper**) extracts every active and inactive ad from Meta's public **Ad Library** at `facebook.com/ads/library/` — across **Facebook, Instagram, Messenger and Audience Network**. **No login, no API key, no browser** — pure HTTP, global coverage.

Search by keyword, audit every ad a competitor's Page is running, or sweep one keyword across many countries — and get back creative URLs (HD/SD video, images, carousels), ad copy, CTAs, landing-page links, advertiser details and, for political/issue and EU ads, **spend and impressions**.

### Scrape Facebook & Instagram ads — no login, no API key

This is a **no-login Facebook ad spy** tool. It needs no Facebook account, no access token and no developer app — it reads the same public Ad Library page any visitor sees:

- **No login / no API key / no token** — paste your keywords or Page IDs and run.
- **All commercial ads, every country** — not limited to political ads or to the EU.
- **Facebook + Instagram + Messenger + Audience Network** in one run via `publisherPlatforms`.
- **Pure HTTP, no headless browser** — fast (~1–3 s per ~30-ad page) and reliable.

### Meta Ad Library API alternative — all commercial ads, no approval

Buyers usually arrive after hitting the wall of the **official Meta Ad Library API**. This actor is the no-approval alternative:

| | This Meta Ad Library Scraper | Official Meta Ad Library API |
|---|---|---|
| Facebook account | **Not required** | Required |
| Identity verification (gov ID) | **Not required** | Required |
| Access token | **None** | Required, and expires |
| Ad coverage | **All commercial ads, all countries** | Mainly political/issue ads globally; *all* ads only for EU/UK |
| Output | Structured rows, export to CSV/JSON | Raw API JSON |
| Setup | Paste input, run | Developer app + verification + token |

If you want **all** advertisers' commercial creatives in **any** country without Meta's identity-verification and expiring-token process, this scraper is the practical path.

### Spy on competitor ads & audit any advertiser by Page ID

- **Keyword search** — find every advertiser running ads for a term (`nike`, `skincare`, `crypto`) in your chosen countries.
- **Advertiser audit** — pass one or more Facebook **Page IDs** in `advertiser` mode to pull every ad a competitor is or was running, historically.
- **Branded-content unmasking** — when an ad is influencer/branded content, the output surfaces the **true advertiser** behind the post.
- **Track over time** — schedule runs to monitor a competitor's active ads, new creatives and landing pages.

> **Find a Page ID:** open the advertiser in the Ad Library and read `view_all_page_id=<ID>` from the URL.

### What ad data you can extract

Every field below is verified end-to-end against the live Ad Library:

- **Ad ID** (`ad_archive_id`) + a one-click link to view it on `facebook.com/ads/library`
- **Active / inactive** flag and **start / end dates** (ISO 8601)
- **Advertiser Page**: `page_id`, `page_name`, profile URL + picture, page like count, page categories
- **Branded-content advertiser** (when applicable) — the *true* advertiser behind influencer posts
- **Creative**: HD + SD video URLs, watermarked variants, video thumbnail, full image set (original + resized), **carousel cards**, extra gallery creatives
- **Copy**: `body_text` (caption), `title`, `caption` (display URL), `link_description`
- **Call-to-action**: `cta_text`, `cta_type` (`SHOP_NOW`, `INSTALL_NOW`, `LEARN_MORE`, …)
- **Landing page**: `link_url` (the destination the ad sends to)
- **Format**: `display_format` (`VIDEO`, `IMAGE`, `DCO`, `DPA`, …)
- **Regulated disclosure** (political/issue + EU ads): `spend` range, `currency`, `impressions_text`, `reach_estimate`, `byline` ("Paid for by …"), `disclaimer_label`
- **Categories**, `gated_type`, `state_media_run_label`, `contains_digital_created_media`

#### Output example

```json
{
  "ad_archive_id": "1234567890123456",
  "ad_library_url": "https://www.facebook.com/ads/library/?id=1234567890123456",
  "is_active": true,
  "page_id": "15087023444",
  "page_name": "Nike",
  "page_profile_uri": "https://www.facebook.com/nike",
  "publisher_platforms": ["FACEBOOK", "INSTAGRAM"],
  "display_format": "VIDEO",
  "title": "Nike Air Max",
  "body_text": "Just Do It. Shop the new collection.",
  "cta_text": "Shop now",
  "cta_type": "SHOP_NOW",
  "link_url": "https://www.nike.com/air-max",
  "video_hd_url": "https://video.xx.fbcdn.net/...hd.mp4",
  "video_sd_url": "https://video.xx.fbcdn.net/...sd.mp4",
  "images": ["https://scontent.xx.fbcdn.net/...jpg"],
  "start_date": "2026-05-01",
  "end_date": null,
  "spend": null,
  "impressions_text": null,
  "currency": null
}
```

> `spend`, `impressions_text` and `reach_estimate` are populated **only** for political/issue ads and EU ads — Meta does not disclose them for ordinary commercial ads.

### Download ad creatives — video (HD/SD), image & carousel

Build a swipe file or creative bank straight from the data. Every ad row carries direct creative URLs — **HD and SD video**, the **full image set**, and **carousel cards** — so you can download or archive the actual creatives, not just metadata. Filter with `mediaType=video` (or `image`) to pull only the format you want.

### Find winning products & ad creatives (ecommerce & dropshipping)

For DTC media buyers and dropshippers, the Ad Library is a winning-product radar:

- Search a product or niche, sort by what's been **running longest** (`start_date` + still `is_active`) — long-running ads usually mean profitable ads.
- Grab the **creative** (video/image) and the **landing page** (`link_url`) to study the offer and funnel.
- Chain `link_url` into a store-fingerprinting tool such as the **[Shopify Store Leads Scraper](https://apify.com/buff_pineapple/shopify-store-leads-scraper)** to profile the destination store.

### Track political & issue ads: spend, impressions & EU transparency

A defensible moat for researchers, journalists, watchdogs and compliance teams. Set `adType` to one of Meta's regulated categories — **political/issue, employment, housing or credit** — and the actor returns the mandated transparency data: **spend range, impressions range, reach estimate, the "Paid for by" byline and disclaimer label**. Combine with `countries` for cross-border EU/DSA ad-transparency monitoring.

### Filters supported (verified)

| Filter | Values |
|---|---|
| **Keyword** | any string (`nike`, `allbirds`, `climate`) |
| **Page ID** | one or many Facebook Page IDs (advertiser audit) |
| **Country** | ISO-2 codes, multi-country, or `ALL` for global |
| **Active status** | `active` / `inactive` / `all` |
| **Ad type** | `ALL` / `POLITICAL_AND_ISSUE_ADS` / `EMPLOYMENT_ADS` / `HOUSING_ADS` / `CREDIT_ADS` |
| **Media type** | `all` / `image` / `video` / `meme` |
| **Publisher platforms** | `FACEBOOK`, `INSTAGRAM`, `MESSENGER`, `AUDIENCE_NETWORK` |
| **Content languages** | ISO codes |

### Run modes

| Mode | Behavior |
|---|---|
| `search` (default) | Keyword search across the chosen countries |
| `advertiser` | Pass `pageIds` to audit every ad a given Page is or was running |
| `multi_country` | Same keyword across many countries — output tagged with `country` |

### Example inputs

**1. Daily competitor spy in 3 markets**

```json
{ "mode": "search", "queries": ["nike"], "countries": ["US", "GB", "DE"], "activeStatus": "active", "maxAdsPerQuery": 200 }
```

**2. Full audit of one advertiser**

```json
{ "mode": "advertiser", "pageIds": ["15087023444"], "countries": ["US"], "activeStatus": "all", "maxAdsPerQuery": 1000 }
```

**3. Political ad watch in the US**

```json
{ "mode": "search", "queries": ["climate", "election"], "countries": ["US"], "adType": "POLITICAL_AND_ISSUE_ADS", "maxAdsPerQuery": 500 }
```

**4. Video-only beauty creative bank**

```json
{ "mode": "search", "queries": ["skincare", "makeup"], "countries": ["US", "GB"], "mediaType": "video", "maxAdsPerQuery": 100 }
```

### How it works

Meta's Ad Library is public, but its frontend runs a short anti-bot handshake before serving data:

1. The actor GETs `/ads/library/?…`. If Meta returns a 403 challenge page, it POSTs the challenge URL once and re-GETs. This is a documented public handshake — no login or credentials.
2. It extracts `lsd` + a few session tokens from the resulting HTML.
3. Every ad-listing query goes to `POST /api/graphql/` with the same `fb_api_req_friendly_name=AdLibrarySearchPaginationQuery` the Ad Library UI itself uses.
4. Pagination uses Meta's own `page_info.end_cursor`.

Because everything is plain HTTP, runs are fast and memory-light — no headless browser to crash or slow you down.

### Integrations & export — CSV, JSON, Google Sheets, n8n, Make, Zapier

Every run writes to an Apify dataset you can download as **CSV, Excel, JSON or JSONL**, or pull via the **Apify API** and the official **Python / JavaScript** clients. Connect it to **Google Sheets, n8n, Make, Zapier** or an **MCP**-compatible AI agent to automate competitor-ad monitoring and creative pipelines.

### Pricing (PAY\_PER\_EVENT)

| Event | Price |
|---|---|
| Actor start | $0.00005 / GB of memory (≈ $0.0002 per run at the 4 GB default) |
| Per ad row extracted | $0.001 |

A typical run pulling 200 ads/country across US/GB/DE (600 ads) ≈ **$0.60**. A full advertiser audit pulling 1,000 ads in one country ≈ **$1.00**. Platform usage (compute, proxy, traffic) is included in the per-ad price — pay per ad, **no monthly subscription**.

### FAQ

#### Do I need a Facebook account or API key?

No. There's no login, no access token and no developer app to register. The actor reads the public Meta Ad Library over plain HTTP, so you just enter keywords or Page IDs and run it.

#### Is it legal to scrape the Meta Ad Library?

The Ad Library is a public transparency service Meta is required to publish under the EU DSA and national laws. The actor reads only publicly displayed ad data — no login session, no user content, nothing behind authentication. Use the data within applicable laws.

#### How is this different from the official Meta Ad Library API?

The official API requires a Meta developer account, government-ID verification and an access token that expires, and it mainly archives political/issue ads globally (all ads only for EU/UK). This scraper returns **all commercial ads in any country** with no account or token.

#### Can I scrape Instagram ads too?

Yes. It covers **Facebook, Instagram, Messenger and Audience Network**. Leave `publisherPlatforms` empty for all, or set it to `INSTAGRAM` to keep only Instagram placements.

#### Can I download ad videos and images?

Yes. Each ad row includes direct **HD and SD video URLs**, the **full image set** and **carousel cards**, so you can download or archive the real creatives. Use `mediaType=video` or `image` to filter.

#### Can I get ad spend, impressions and reach?

Yes — for **political/issue ads and EU ads**, where Meta is required to disclose them. You get `spend` (range), `impressions_text` (range), `reach_estimate` and the "Paid for by" byline. Commercial ads don't expose spend.

#### How do I audit every ad from one advertiser?

Use `advertiser` mode and pass the Facebook **Page ID(s)**. Find a Page ID by opening the advertiser in the Ad Library and reading `view_all_page_id=<ID>` from the URL.

#### Which countries are supported and how much does it cost?

Any ISO-2 country code, or `ALL` for global. Pricing is pay-per-event — roughly **$0.60 for 200 ads/country across 3 countries** — with no monthly fee.

### Other actors by buff\_pineapple

- **[TikTok Top Ads Scraper](https://apify.com/buff_pineapple/tiktok-top-ads-scraper)** — TikTok Creative Center top-ads intelligence (creative, budget tier, landing page).
- **[Shopify Store Leads Scraper](https://apify.com/buff_pineapple/shopify-store-leads-scraper)** — fingerprint the stores behind ad landing pages; pull products + contact leads.
- **[Google Maps Scraper](https://apify.com/buff_pineapple/google-maps-scraper)** — business leads with phone & website, no API key.
- **[Google Reviews Scraper](https://apify.com/buff_pineapple/google-reviews-scraper)** — full Google Maps review text + place profiles.
- **[Trustpilot Reviews Scraper](https://apify.com/buff_pineapple/trustpilot-reviews-scraper)** — every Trustpilot review + company TrustScore.
- **[Yelp Scraper](https://apify.com/buff_pineapple/yelp-scraper)** — Yelp business profiles + reviews.
- **[Zillow Listings Scraper](https://apify.com/buff_pineapple/zillow-listings-scraper)** — homes for sale, rent and sold with full details.

### Ethics & legality

The Meta Ad Library is a public transparency service Meta publishes under the EU DSA and various national laws. The actor accesses only publicly displayed information, holds no login session, and observes Meta's expected client handshake. It does not access user content, private posts, or any data behind authentication.

### License

MIT.

# Actor input Schema

## `mode` (type: `string`):

search: keyword search; advertiser: by Page IDs; multi\_country: same keyword across many countries.

## `queries` (type: `array`):

One or more keywords (for `search`/`multi_country`). Ignored in `advertiser` mode.

## `pageIds` (type: `array`):

Facebook Page IDs to audit. Find a Page ID via the Ad Library search → click an advertiser → URL contains view\_all\_page\_id=<ID>.

## `countries` (type: `array`):

ISO-2 country codes. Common: US, GB, DE, FR, IT, ES, NL, BR, JP, IN, MX, CA, AU. Pass ALL for global.

## `activeStatus` (type: `string`):

Filter by whether the ad is currently running.

## `adType` (type: `string`):

ALL = every ad. The other options surface only ads classified into Meta's regulated categories (political, employment, housing, credit), which include spend & impressions disclosure.

## `mediaType` (type: `string`):

Filter by creative media type.

## `publisherPlatforms` (type: `array`):

Empty = all. Otherwise pick from FACEBOOK, INSTAGRAM, MESSENGER, AUDIENCE\_NETWORK.

## `contentLanguages` (type: `array`):

Language ISO codes (en, es, de, fr, pt, ja, ar, …). Empty = all languages.

## `maxAdsPerQuery` (type: `integer`):

Caps each Cartesian-product combo. The actor paginates until this is reached or the source returns no more.

## `pageSize` (type: `integer`):

How many ads to ask for per GraphQL call. 30 matches the UI; larger values may be capped server-side.

## `proxyConfiguration` (type: `object`):

REQUIRED for cloud runs — Meta rate-limits datacenter IPs. Use Apify Proxy with RESIDENTIAL group for reliable access.

## `maxConcurrency` (type: `integer`):

Accepted for backward compatibility but has no effect — the scraper always runs combos one at a time because Meta's endpoint rate-limits concurrent traffic.

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "nike",
    "allbirds"
  ],
  "pageIds": [],
  "countries": [
    "US"
  ],
  "activeStatus": "active",
  "adType": "ALL",
  "mediaType": "all",
  "publisherPlatforms": [],
  "contentLanguages": [],
  "maxAdsPerQuery": 100,
  "pageSize": 30,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "maxConcurrency": 3
}
```

# Actor output Schema

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

No description

# 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 = {
    "queries": [
        "nike",
        "allbirds"
    ],
    "countries": [
        "US"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("buff_pineapple/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 = {
    "queries": [
        "nike",
        "allbirds",
    ],
    "countries": ["US"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "queries": [
    "nike",
    "allbirds"
  ],
  "countries": [
    "US"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call buff_pineapple/meta-ad-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,buff_pineapple/meta-ad-library-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4e5Zcf2MDtpDnrVzE/builds/VzGSJD7JrdxEqWeye/openapi.json
