# Meta Ad Library Scraper (`silentflow/meta-ad-library-scraper`) Actor

Scrape Facebook and Instagram ads from the Meta Ad Library by keyword or page URL, no login needed. Extract ad creatives, images, videos, carousel cards, copy, CTA, landing pages, advertiser details, dates and platforms. Track competitor ads, build swipe files and analyze ad strategy at scale.

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

## Pricing

from $0.50 / 1,000 ads

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

**Turn the Meta Ad Library into clean, structured ad data you can actually work with. Every active and inactive ad from any advertiser or keyword, with the full creative, in seconds.**

Scrape Facebook and Instagram ads straight from Meta's public Ad Library. Search by keyword, pull every ad a page is running, or paste an Ad Library URL. Get the headline, body, call to action, landing page, images, videos, carousel cards, advertiser identity, run dates, and platform spread for each ad. No login, no API key, no cookies.

### How it works

![How the Meta Ad Library Scraper works](https://api.apify.com/v2/key-value-stores/P7VmfWWl3QPd9rjPE/records/how-it-works-v6.png)

1. Drop in a keyword search URL, a Facebook Page URL, or an Ad Library URL.
2. Set how many ads you want.
3. Get back a clean row per ad, with the full creative and advertiser data, ready for export.

### ✨ Why teams choose this over other Meta Ad Library scrapers

Spending hours scrolling the Ad Library and screenshotting competitor ads? Running scrapers that choke after a few hundred results? Tired of getting back a headline and nothing else?

- 💰 **Pay per result, not per minute.** No compute costs, proxies included. You pay for ads delivered, period. A run that returns nothing costs nothing.
- 🔁 **Drop-in compatible, plus extras.** Same inputs and the same output structure as the most popular Ad Library scraper, so you can switch your pipeline over with zero rewrites, and get cleaner fields on top.
- 🧹 **Flat, analysis-ready output.** Other scrapers hand you the raw nested object and leave you to dig through `snapshot.cards[].video_hd_url`. We pull the essentials up to the top level: `cta`, `landing_url`, `title`, `body`, plus `image_urls` and `video_urls` as flat lists. Open the CSV and the columns you need are right there.
- 🖼️ **Every creative URL in one list.** All images and all videos across single ads and carousels are flattened into `image_urls` and `video_urls`. Build a swipe file with one column, not a JSON crawl.
- ⏳ **Spot winning ads instantly.** Each ad carries `days_running`, how long it has actually been live. Long-running ads are the ones that work, sorted in seconds.
- 🧱 **The full creative, not just the caption.** Every image, every video, and every carousel card comes through with its own link, call to action, and copy. Nothing is dropped.
- 🆔 **No login, no account, no API key.** This reads the public Ad Library directly. Nothing to authenticate, nothing to get rate limited on your own account.
- 🌍 **Any country, Facebook and Instagram.** Pull ads targeted to any market and see exactly which platforms each ad runs on, from one input.
- 🏷️ **Advertiser intelligence built in.** Every ad carries the advertiser's page likes. Turn on ad details and each ad also gets `advertiser_name`, `advertiser_ig_followers`, `advertiser_likes`, `advertiser_category`, and EU reach as flat columns. Size up who is spending in one glance.
- 📊 **Reliable at volume.** No login means no account to get rate limited, and the scraper recovers from hiccups on its own. In testing it held a perfect success rate across dozens of parallel runs in 10+ countries.
- 📦 **60+ fields per ad.** The fields other scrapers skip, like the carousel breakdown, the collation of duplicate ads, total active time, and the advertiser profile, are often the ones that tell you what is actually working.

### 🎯 What you can do with Meta Ad Library data

| Team | What they build |
|---|---|
| Performance marketing | A live feed of every competitor ad by keyword and country, refreshed before each campaign sprint |
| Creative strategy | A searchable swipe file of winning images, videos, and carousels pulled from the top spenders in a niche |
| Brand and comms | A monitor that flags when a competitor launches a new campaign or kills an old one |
| Agencies | Client pitch decks backed by the actual ads competitors are running, not guesses |
| Ecommerce and DTC | A catalog of product ads and landing pages across an entire category to spot pricing and offer angles |
| Market research | A cross-country comparison of how the same brand advertises in different regions and languages |
| Affiliate and dropshipping | A scan of which products and creatives are scaling, by how many active ad variants a page is running |

### 📥 Input parameters

#### Sources

| Field | Type | Description |
|---|---|---|
| `urls` | array | One or more Ad Library search URLs or advertiser page URLs. This is the only required field. |

A search URL looks like `https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all`. An advertiser page URL can be a simple `https://www.facebook.com/nike` or the Ad Library URL that contains `view_all_page_id`. Page URLs return every ad that advertiser is running. You can mix both in one run.

#### Limits

| Field | Type | Default | Description |
|---|---|---|---|
| `count` | integer | 100 | Total ads to collect across all URLs. Leave empty for no cap. |
| `limitPerSource` | integer | (none) | Maximum ads to collect per input URL. |

#### Page URL filters

These apply when an input is an advertiser page URL.

| Field | Type | Default | Description |
|---|---|---|---|
| `scrapePageAds.activeStatus` | select | All | All, active only, or inactive only. |
| `scrapePageAds.countryCode` | string | ALL | Two letter country code, or ALL. |

#### Options

| Field | Type | Default | Description |
|---|---|---|---|
| `scrapeAdDetails` | boolean | false | Also fetch the advertiser profile (followers, likes, page spend) and EU reach breakdown for each ad. |
| `cleanOutput` | boolean | false | Return only the flat, analysis-ready fields instead of the full raw object. Best for tidy CSV. |
| `runTag` | string | (none) | A label written into every output row, handy for tracking which run produced which data. |
| `debugMode` | boolean | false | Verbose logs for troubleshooting. |

### 📊 Output data

Each ad is one row. Example of a keyword search result:

```json
{
  "ad_archive_id": "1869276447125570",
  "ad_library_url": "https://www.facebook.com/ads/library/?id=1869276447125570",
  "page_id": "15087023444",
  "page_name": "Nike",
  "is_active": true,
  "start_date": 1744675200,
  "start_date_formatted": "2025-04-15",
  "end_date": 1763712000,
  "end_date_formatted": "2025-11-21",
  "currency": "USD",
  "publisher_platform": ["FACEBOOK", "INSTAGRAM"],
  "collation_count": 2,
  "total_active_time": 1209600,
  "cta": "Shop Now",
  "landing_url": "https://www.nike.com/",
  "title": "Nike Air Monarch IV",
  "body": "Get the gear not afraid to put in the work.",
  "image_urls": ["https://scontent.xx.fbcdn.net/v/t45.1600-4/..."],
  "video_urls": [],
  "days_running": 135,
  "total_variants": 2,
  "snapshot": {
    "body": { "text": "Get the gear not afraid to put in the work." },
    "title": "Nike Air Monarch IV",
    "caption": "nike.com",
    "cta_text": "Shop Now",
    "cta_type": "SHOP_NOW",
    "link_url": "https://www.nike.com/",
    "link_description": "Nike delivers innovative products, experiences and services.",
    "page_profile_picture_url": "https://scontent.xx.fbcdn.net/...",
    "page_like_count": 39000000,
    "display_format": "IMAGE",
    "images": [{ "original_image_url": "https://scontent.xx.fbcdn.net/..." }],
    "videos": [],
    "cards": []
  },
  "runTag": "competitor-scan"
}
````

Example of a video ad with a carousel:

```json
{
  "ad_archive_id": "1191898553123641",
  "ad_library_url": "https://www.facebook.com/ads/library/?id=1191898553123641",
  "page_name": "Whatnot",
  "is_active": true,
  "publisher_platform": ["FACEBOOK", "INSTAGRAM", "MESSENGER"],
  "snapshot": {
    "display_format": "DCO",
    "cta_text": "Install Now",
    "cta_type": "INSTALL_MOBILE_APP",
    "cards": [
      {
        "title": "Whatnot",
        "body": "Live shopping for the things you love.",
        "cta_text": "Install Now",
        "link_url": "https://itunes.apple.com/app/id1093315431",
        "video_hd_url": "https://video.xx.fbcdn.net/...",
        "video_preview_image_url": "https://scontent.xx.fbcdn.net/...",
        "resized_image_url": "https://scontent.xx.fbcdn.net/..."
      }
    ]
  }
}
```

With `scrapeAdDetails` enabled, each ad also carries an `advertiser` block (and `aaa_info` EU reach for EU and political ads):

```json
{
  "page_name": "Nike",
  "advertiser": {
    "ad_library_page_info": {
      "page_info": {
        "page_name": "Nike",
        "ig_username": "nike",
        "ig_followers": 291936445,
        "likes": 39000000,
        "page_category": "Sportswear store",
        "page_profile_uri": "https://www.facebook.com/nike/"
      },
      "page_spend": {
        "is_political_page": false,
        "lifetime_by_disclaimer": []
      }
    },
    "page": { "about": { "text": "Just Do It." } }
  },
  "aaa_info": {
    "eu_total_reach": 1840000,
    "age_audience": { "min": 18, "max": 65 },
    "gender_audience": "ALL",
    "age_country_gender_reach_breakdown": [
      { "country": "DE", "age_gender_breakdowns": [ { "age_range": "18-24", "male": 12000, "female": 9000 } ] }
    ]
  }
}
```

### 🗂️ Data fields

| Category | Fields |
|---|---|
| Quick fields (flat) | `cta`, `cta_type`, `landing_url`, `title`, `body`, `caption`, `display_format`, `image_urls`, `video_urls`, `days_running`, `total_variants`, `page_likes`, `advertiser_logo` |
| Advertiser (flat, with `scrapeAdDetails`) | `advertiser_name`, `advertiser_category`, `advertiser_ig_followers`, `advertiser_likes`, `advertiser_ig_username`, `advertiser_page_url`, `advertiser_about`, `eu_total_reach` |
| Identity | `ad_archive_id`, `ad_library_url`, `page_id`, `page_name`, `runTag` |
| Status and timing | `is_active`, `start_date`, `end_date`, `start_date_formatted`, `end_date_formatted`, `total_active_time` |
| Reach and grouping | `publisher_platform`, `collation_count`, `collation_id`, `currency`, `categories` |
| Creative copy | `snapshot.body.text`, `snapshot.title`, `snapshot.caption`, `snapshot.cta_text`, `snapshot.cta_type` |
| Landing page | `snapshot.link_url`, `snapshot.link_description` |
| Media | `snapshot.images`, `snapshot.videos`, `snapshot.cards`, `snapshot.display_format` |
| Advertiser | `snapshot.page_profile_picture_url`, `snapshot.page_profile_uri`, `snapshot.page_like_count`, `snapshot.page_categories` |
| Transparency | `regional_regulation_data`, `targeted_or_reached_countries`, `contains_sensitive_content`, `contains_digital_created_media` |
| Ad details (when `scrapeAdDetails` on) | `advertiser.ad_library_page_info.page_info` (followers, likes, category), `advertiser.ad_library_page_info.page_spend`, `aaa_info` (EU age, gender, country reach) |

<details>
<summary><b>See the full flat field reference</b></summary>

| Field | Type | What it is |
|---|---|---|
| `page_name` | string | Advertiser name |
| `is_active` | boolean | Whether the ad is live now |
| `days_running` | number | Days the ad has been running so far |
| `cta` | string | Call to action button text |
| `landing_url` | string | Page the ad links to |
| `title` | string | Ad headline |
| `body` | string | Ad copy |
| `image_urls` | array | Every image creative, including carousel cards |
| `video_urls` | array | Every video creative, including carousel cards |
| `total_variants` | number | Near-duplicate variants of the creative |
| `publisher_platform` | array | Facebook, Instagram, Messenger, Audience Network |
| `start_date_formatted` | string | Start date, YYYY-MM-DD |
| `end_date_formatted` | string | End date, YYYY-MM-DD |
| `ad_archive_id` | string | Meta Ad Library ID |
| `ad_library_url` | string | Permalink to the ad |
| `page_id` | string | Numeric advertiser Page ID |
| `currency` | string | Currency of spend figures, when published |
| `runTag` | string | Your run label |

</details>

### 🚀 Examples

#### Get the latest Nike ads in the US

```json
{
  "urls": [
    { "url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all" }
  ],
  "count": 50
}
```

#### Pull every ad a specific advertiser is running

```json
{
  "urls": [{ "url": "https://www.facebook.com/nike" }],
  "scrapePageAds.activeStatus": "active"
}
```

#### Scan a whole niche for video ads only

```json
{
  "urls": [
    { "url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=protein%20powder&media_type=video&search_type=keyword_unordered" }
  ],
  "count": 200
}
```

#### Compare one brand across two countries

```json
{
  "urls": [
    { "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=adidas&search_type=keyword_unordered&media_type=all" },
    { "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=GB&q=adidas&search_type=keyword_unordered&media_type=all" }
  ],
  "count": 300,
  "runTag": "adidas-us-vs-uk"
}
```

#### Get only the active ads from one advertiser

```json
{
  "urls": [{ "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&view_all_page_id=15087023444" }],
  "scrapePageAds.activeStatus": "active",
  "scrapePageAds.countryCode": "US",
  "limitPerSource": 100
}
```

#### Add advertiser profiles and EU reach

```json
{
  "urls": [
    { "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=DE&q=insurance&search_type=keyword_unordered&media_type=all" }
  ],
  "count": 50,
  "scrapeAdDetails": true
}
```

### 🤖 Copy to your AI assistant

Paste this block into Claude, ChatGPT, or Cursor to give it full context about this scraper:

```
You have access to the Meta Ad Library Scraper on Apify: silentflow/meta-ad-library-scraper

It scrapes Facebook and Instagram ads from the public Meta Ad Library. No login required.

Input schema:
- urls (required, array of {url}): Ad Library search URLs or advertiser page URLs (with view_all_page_id)
- count (integer, default 100): total ads across all URLs, empty = unlimited
- limitPerSource (integer): max ads per input URL
- scrapeAdDetails (boolean, default false): add advertiser profile + EU reach per ad
- cleanOutput (boolean, default false): return only the flat fields, no raw nested object
- scrapePageAds.activeStatus (string, default all): all, active, inactive (Page URLs)
- scrapePageAds.period (string): "", last24h, last7d, last14d, last30d (Page URLs)
- scrapePageAds.sortBy (string, default impressions_desc): impressions_desc, most_recent (Page URLs)
- scrapePageAds.countryCode (string, default ALL): 2-letter country code or ALL (Page URLs)
- runTag (string): label written into every output row

Output per ad (60+ fields). Flat quick fields: cta, cta_type, landing_url, title, body,
caption, display_format, image_urls[], video_urls[], days_running, total_variants,
page_likes, advertiser_logo. Plus ad_archive_id, ad_library_url, page_id, page_name,
is_active, start_date_formatted, end_date_formatted, publisher_platform, runTag, and the
full raw object including a nested snapshot (cards[], images[], videos[], etc.).
With scrapeAdDetails: flat advertiser_name, advertiser_ig_followers, advertiser_likes,
advertiser_category, advertiser_about, eu_total_reach. Set cleanOutput to drop the raw object.

Pay per result. Proxies included. Use apify-client for Python or JS.
```

### 💻 Integrations

#### Build a competitor ad monitor in Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("silentflow/meta-ad-library-scraper").call(run_input={
    "urls": [{"url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"}],
    "count": 200,
})

## Flat fields make this trivial: list live ads, their CTA, landing page and how long they have run
for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    if ad.get("is_active"):
        print(ad["page_name"], "|", ad["cta"], "->", ad["landing_url"], "|", ad["days_running"], "days")
```

#### Build a creative swipe file in JavaScript

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('silentflow/meta-ad-library-scraper').call({
  urls: [{ url: 'https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&view_all_page_id=15087023444' }],
  count: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();

// image_urls and video_urls are already flattened across single ads and carousels
const images = items.flatMap(ad => ad.image_urls || []);
const videos = items.flatMap(ad => ad.video_urls || []);
console.log(`Swipe file: ${images.length} images, ${videos.length} videos`);
```

#### Export to CSV from the command line

```bash
curl "https://api.apify.com/v2/datasets/YOUR_DATASET_ID/items?format=csv&token=YOUR_APIFY_TOKEN" -o meta_ads.csv
```

### 📈 Performance

| Metric | Value |
|---|---|
| Login required | None |
| Platforms covered | Facebook, Instagram, Messenger, Audience Network |
| Ads per page request | Streamed continuously with automatic pagination |
| Typical run | A few hundred ads in well under a minute |
| Output format | One clean row per ad |

### 💾 Data export

Results land in an Apify dataset with a clean table view (advertiser, active, days live, CTA, landing page, images, videos) so you can scan ads without leaving the console. Export from the dataset tab as JSON, CSV, Excel, HTML, RSS, or XML. To pull data programmatically, use the dataset API:

```
https://api.apify.com/v2/datasets/YOUR_DATASET_ID/items?format=csv&token=YOUR_APIFY_TOKEN
```

### 💡 Tips for best results

- Build your search URL on the Ad Library website first, then paste it in. Whatever filters you set there, country, keyword, media type, active status, carry straight into the scraper.
- Use `count` for a quick sample and `limitPerSource` when you want an even number of ads from each of several URLs.
- To track a single advertiser over time, run the same Page URL on a schedule and compare `is_active` and `start_date` between runs.
- Sort the dataset by `days_running` to surface the longest running ads first. Those are usually the winners worth copying.
- `image_urls` and `video_urls` give you every creative as a flat list, so a swipe file is one column away in CSV.
- `total_variants` tells you how many near duplicate variants an ad has. A high number is a strong signal a creative is scaling.
- Set a `runTag` per project so you can tell campaigns apart when you merge several runs into one dataset.

### ❓ FAQ

**What exactly does this scrape?**
Public ads from the Meta Ad Library: the creative (images, videos, carousel cards), the copy, the call to action, the landing page link, the advertiser page, run dates, active status, and the platforms each ad runs on.

**Can I search by keyword and by advertiser?**
Yes. Paste a keyword search URL to scan everything matching a term, or an advertiser page URL like facebook.com/nike to pull every ad that advertiser is running. You can mix both in one run.

**Do I need a Facebook account or API key?**
No. The Ad Library is public. There is no login, no API key, and no cookies to manage.

**Which countries and platforms are covered?**
Any country supported by the Ad Library, and ads across Facebook, Instagram, Messenger, and Audience Network. The platform list comes through on every ad.

**How fresh is the data?**
It is pulled live from the Ad Library at the moment you run the scraper, so it reflects what is showing right now, including ads that went live today.

**How many ads can I pull?**
As many as the Ad Library returns for your URL. Use `count` and `limitPerSource` to cap the total when you only need a sample.

**Can I scrape several searches at once?**
Yes. Put as many search URLs and Page URLs as you want in the `urls` list and they are processed in one run.

**Do I have to dig through nested JSON?**
No. The fields most people need, the CTA, landing page, headline, body, and every image and video URL, are pulled up to the top level as `cta`, `landing_url`, `title`, `body`, `image_urls`, and `video_urls`. Open the CSV and the columns are right there. The full raw object is still included if you want it.

**What does Scrape ad details add?**
With it on, each ad also gets an `advertiser` block (page followers, likes, page spend) and, for EU and political ads, an `aaa_info` block with the EU age, gender, and country reach breakdown. It is off by default because it makes one extra request per ad.

**Why are spend and impression numbers sometimes empty?**
Meta only publishes spend, impression, and audience reach figures for ads about social issues, elections, or politics, and for EU transparency. Commercial ads do not carry those numbers, so those fields are empty for them. Everything else, the creative and advertiser data, is always there.

### ⚖️ Legal

This Actor extracts publicly available data from the Meta Ad Library. It does not bypass any login, paywall, or CAPTCHA. Users are responsible for complying with Meta's terms of service and applicable laws in their jurisdiction. The data returned is informational; verify accuracy for regulated use cases.

### 📬 Support

Need something this scraper doesn't do yet? We ship features fast.

- Feature requests go straight to our backlog
- Enterprise needs? We do custom integrations and high-volume plans
- Pricing questions? Check the Monetization tab on the actor page

Response time: usually under 24 hours.

Check out our other scrapers: [silentflow on Apify](https://apify.com/silentflow)

# Actor input Schema

## `urls` (type: `array`):

Meta Ad Library search URLs, advertiser page URLs (facebook.com/<name>), or Ad Library page URLs with view\_all\_page\_id.

## `count` (type: `integer`):

Total number of ads to scrape across all URLs. Leave empty for no limit.

## `limitPerSource` (type: `integer`):

Max ads per input URL. Leave empty to scrape all available.

## `scrapeAdDetails` (type: `boolean`):

Fetch the advertiser profile (followers, likes, page spend) and the EU reach breakdown for each ad. Slower, one extra request per ad.

## `cleanOutput` (type: `boolean`):

Return only the flat, analysis-ready fields (advertiser, creative, dates, image and video URLs) instead of the full raw object. Best for tidy CSV and spreadsheets.

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

Return all ads, only active ones, or only inactive ones.

## `scrapePageAds.period` (type: `string`):

Keep only ads that started in this recent window.

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

Order the advertiser's ads by impressions (default) or most recent first.

## `scrapePageAds.countryCode` (type: `string`):

2-letter ISO country code (uppercase), or ALL.

## `runTag` (type: `string`):

A label added to every output record's runTag field. Handy when you merge several runs into one dataset.

## `debugMode` (type: `boolean`):

Verbose logs for troubleshooting.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"
    },
    {
      "url": "https://www.facebook.com/nike"
    }
  ],
  "count": 100,
  "scrapeAdDetails": false,
  "cleanOutput": false,
  "scrapePageAds.activeStatus": "all",
  "scrapePageAds.period": "",
  "scrapePageAds.sortBy": "impressions_desc",
  "scrapePageAds.countryCode": "ALL",
  "debugMode": false
}
```

# Actor output Schema

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

All ads collected in this run. Export as JSON, CSV, or Excel from the dataset.

# 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 = {
    "urls": [
        {
            "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"
        },
        {
            "url": "https://www.facebook.com/nike"
        }
    ],
    "count": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("silentflow/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 = {
    "urls": [
        { "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all" },
        { "url": "https://www.facebook.com/nike" },
    ],
    "count": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("silentflow/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 '{
  "urls": [
    {
      "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"
    },
    {
      "url": "https://www.facebook.com/nike"
    }
  ],
  "count": 100
}' |
apify call silentflow/meta-ad-library-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Meta Ad Library Scraper",
        "description": "Scrape Facebook and Instagram ads from the Meta Ad Library by keyword or page URL, no login needed. Extract ad creatives, images, videos, carousel cards, copy, CTA, landing pages, advertiser details, dates and platforms. Track competitor ads, build swipe files and analyze ad strategy at scale.",
        "version": "1.0",
        "x-build-id": "5A4xnjZp2o4IOgKDn"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/silentflow~meta-ad-library-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-silentflow-meta-ad-library-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/silentflow~meta-ad-library-scraper/runs": {
            "post": {
                "operationId": "runs-sync-silentflow-meta-ad-library-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/silentflow~meta-ad-library-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-silentflow-meta-ad-library-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "urls"
                ],
                "properties": {
                    "urls": {
                        "title": "🔗 URLs",
                        "type": "array",
                        "description": "Meta Ad Library search URLs, advertiser page URLs (facebook.com/<name>), or Ad Library page URLs with view_all_page_id.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "count": {
                        "title": "Total number of ads",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Total number of ads to scrape across all URLs. Leave empty for no limit."
                    },
                    "limitPerSource": {
                        "title": "Limit per input URL",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Max ads per input URL. Leave empty to scrape all available."
                    },
                    "scrapeAdDetails": {
                        "title": "Scrape ad details",
                        "type": "boolean",
                        "description": "Fetch the advertiser profile (followers, likes, page spend) and the EU reach breakdown for each ad. Slower, one extra request per ad.",
                        "default": false
                    },
                    "cleanOutput": {
                        "title": "Clean output",
                        "type": "boolean",
                        "description": "Return only the flat, analysis-ready fields (advertiser, creative, dates, image and video URLs) instead of the full raw object. Best for tidy CSV and spreadsheets.",
                        "default": false
                    },
                    "scrapePageAds.activeStatus": {
                        "title": "Active status",
                        "enum": [
                            "all",
                            "active",
                            "inactive"
                        ],
                        "type": "string",
                        "description": "Return all ads, only active ones, or only inactive ones.",
                        "default": "all"
                    },
                    "scrapePageAds.period": {
                        "title": "Date range",
                        "enum": [
                            "",
                            "last24h",
                            "last7d",
                            "last14d",
                            "last30d"
                        ],
                        "type": "string",
                        "description": "Keep only ads that started in this recent window.",
                        "default": ""
                    },
                    "scrapePageAds.sortBy": {
                        "title": "Sort by",
                        "enum": [
                            "impressions_desc",
                            "most_recent"
                        ],
                        "type": "string",
                        "description": "Order the advertiser's ads by impressions (default) or most recent first.",
                        "default": "impressions_desc"
                    },
                    "scrapePageAds.countryCode": {
                        "title": "Country",
                        "type": "string",
                        "description": "2-letter ISO country code (uppercase), or ALL.",
                        "default": "ALL"
                    },
                    "runTag": {
                        "title": "Run tag",
                        "type": "string",
                        "description": "A label added to every output record's runTag field. Handy when you merge several runs into one dataset."
                    },
                    "debugMode": {
                        "title": "Debug mode",
                        "type": "boolean",
                        "description": "Verbose logs for troubleshooting.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
