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

Scrape the Meta Ad Library by keyword or advertiser: ad creative, headline, CTA, landing-page URL, run dates, placements, plus the advertiser's page name, ID, likes and category. Find who is advertising. No login.

- **URL**: https://apify.com/scrapersdelight/meta-ad-library-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Lead generation, Social media, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.68 / 1,000 per ad returneds

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

## What is Meta Ad Library Scraper?

Meta Ad Library Scraper extracts **ads running on Facebook, Instagram, Messenger and Threads** from
Meta's public Ad Library — the creative, the landing page, the run dates, and **the advertiser
behind each ad**.

Search by keyword to see everyone advertising in a niche, or by advertiser page ID to pull one
company's entire ad history. **No login and no Facebook account.**

- **Find who is spending on ads** — every row carries the advertiser's page name, page ID, profile
  URL, follower count and business categories
- **See the whole creative** — headline, body copy, call-to-action, landing-page URL, and image or
  video URLs
- **Competitor and market research** — what a rival is running right now, how long each ad has been
  live, and which placements it runs on
- **Filter before you pay** — country, active/inactive, media type and ad category
- Export to Excel, CSV, JSON or HTML; run it on a schedule or from the API

### Why this doubles as a lead list

An advertiser is a business that is **actively spending money to get customers** — which makes this
one of the cleanest B2B lead signals there is. Every ad returns:

`page_name` · `page_id` · `page_profile_url` · `page_likes` · `page_categories` · `link_url`

That last one is the advertiser's own website, which you can push straight into an email or contact
enrichment step. In a sample run for "plumber" in the US, 45 ads came from **39 distinct
advertisers**, each with a website and a follower count.

### What data can this scraper extract?

| | | |
|---|---|---|
| 🏢 Advertiser page name | 🆔 Page ID | 🔗 Page profile URL |
| 👍 Page likes | 🏷️ Page categories | 🌐 Landing-page URL |
| 📝 Headline & body copy | 🔘 Call-to-action | 🖼️ Image / video URLs |
| 📅 Start & end date | ✅ Active status | 📱 Placements (FB/IG/Messenger/Threads) |
| 🎞️ Display format | 🗂️ Card count | 🆔 Ad archive ID + Ad Library URL |

**On spend and impressions:** Meta only publishes reach and spend ranges for **political and
issue ads** — for everything else those fields are empty by design. That's the source data, not the
scraper. To get them, set the ad category to "Issues, elections or politics".

### How much does it cost?

Pay per event — you're charged for what you actually receive.

- **Scraped ad** — the base charge, once per unique ad. Ads are deduplicated by Meta's ad archive
  ID before you're billed.

### How do I use it?

#### ⬇️ Input

```json
{
  "query": "plumber",
  "country": "US",
  "maxItems": 200,
  "activeStatus": "active"
}
```

To pull one advertiser's full history, take the numeric ID from an Ad Library URL
(`…view_all_page_id=1234567890`) and put it in **Advertiser page ID** instead of a search term.

#### ⬆️ Output

One row per ad:

```json
{
  "ad_archive_id": "1409568196971821",
  "page_name": "Honest Plumbing AZ LLC",
  "page_id": "205528589318346",
  "page_profile_url": "https://www.facebook.com/HonestPlumbingAZ/",
  "page_likes": 73268,
  "page_categories": ["Business", "Home Repair"],
  "title": "Need a plumber today?",
  "body_text": "Same-day service across the valley…",
  "cta_text": "Learn more",
  "link_url": "https://www.example-plumbing.com/",
  "is_active": true,
  "start_date": "2026-07-09",
  "end_date": null,
  "publisher_platforms": ["FACEBOOK", "INSTAGRAM", "THREADS"],
  "ad_library_url": "https://www.facebook.com/ads/library/?id=1409568196971821"
}
```

### Common uses

- **Agencies & marketers** — competitor creative research, and a prospect list of businesses
  already paying for ads
- **Lead generation** — advertisers are pre-qualified buyers; pair `link_url` with contact
  enrichment for outbound
- **Market & trend research** — who entered a category, what messaging they use, how long ads run
- **Brand protection** — spot ads impersonating your brand

### Frequently asked questions

**Do I need a Facebook account?**
No. The Ad Library is Meta's public ad-transparency product and this reads it without logging in.

**Do I need residential proxies?**
Yes, and the default is already set correctly. Meta serves datacenter IPs a degraded page that
returns no ad results, so switching to datacenter proxies will produce empty runs.

**Why are spend and impressions empty?**
Meta only publishes them for political and issue ads. See the note above.

**How many ads can I get?**
Meta paginates indefinitely for broad searches — set **Number of ads** to cap the run, or 0 to
collect everything it will serve.

**Is this legal?**
The Ad Library is published by Meta specifically for public transparency and requires no login.
You are still responsible for complying with Meta's Terms of Service and applicable law,
particularly around how you store and use any personal data.

### Your feedback

Hit a bug or want another field? Open an issue on the Issues tab.

# Actor input Schema

## `query` (type: `string`):

Keyword, brand or phrase to search the Ad Library for — e.g. 'plumber', 'meal kit', 'crm software'. Leave empty if you are using an advertiser page ID instead.

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

Pull every ad from ONE advertiser. Take the numeric ID from an Ad Library URL (…view\_all\_page\_id=1234567890). Overrides the search term.

## `country` (type: `string`):

Which country's ad library to search. Meta scopes ads by the country they run in.

## `maxItems` (type: `integer`):

Stop after this many ads. Set 0 for every ad Meta will serve for the search.

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

Currently running ads, ads that have stopped, or both.

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

'Issues, elections or politics' is the only category where Meta publishes spend and impression ranges.

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

Restrict to a creative format.

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

**Residential proxy is required.** Measured 2026-07-29: Meta serves datacenter IPs a degraded page that never returns ad results, while residential works. The default below is already correct — changing it to datacenter will produce empty runs.

## `requestDelayMs` (type: `integer`):

Pacing between pagination calls. Lower is faster but more likely to be throttled.

## Actor input object example

```json
{
  "query": "plumber",
  "country": "US",
  "maxItems": 50,
  "activeStatus": "all",
  "adType": "all",
  "mediaType": "all",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "requestDelayMs": 700
}
```

# Actor output Schema

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

Ad creative (headline, body, CTA, landing page, media) plus the advertiser: page name, page ID, page URL, likes and categories.

# 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 = {
    "query": "plumber",
    "country": "US",
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/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 = {
    "query": "plumber",
    "country": "US",
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/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 '{
  "query": "plumber",
  "country": "US",
  "maxItems": 50
}' |
apify call scrapersdelight/meta-ad-library-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/5pt2nXG77HIatbVd1/builds/E83qscPOt7fL0gMiC/openapi.json
