# Facebook Ads Library Scraper (`crawloop/facebook-ads-library-scraper`) Actor

Scrape the Facebook Ads Library by keyword, Page ID, or Ad Library URL. Export ad copy, call to action, landing URL, publisher platforms, collation count, and how many days each ad has been running.

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

## Pricing

from $1.99 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Facebook Ads Library Scraper

Public competitor ads from the Meta Ad Library: Facebook, Instagram, Messenger, and other placements that appear in one search. No Facebook login.

This Facebook Ads Library Scraper searches by keyword, advertiser Page ID, or a pasted Ad Library URL and returns ad copy, the call to action, landing URL, creative format, publisher platforms, how many variants are running together, and how many days the ad has been active.

| Meta Ad Library | TikTok top ads |
| :--- | :--- |
| Facebook Ads Library Scraper ◄── you are here | [TikTok Ads Scraper](https://apify.com/crawloop/tiktok-ads-scraper) |

### When to use it

Use this Actor when you need a repeatable export of ads a brand is running in a country: creative tests, landing pages, and which ads have stayed up the longest.

Skip it for Facebook Marketplace listings, profile posts, or ad-account metrics from Ads Manager. This Actor reads the public Ad Library only. Marketplace classifieds are [Facebook Marketplace Scraper](https://apify.com/crawloop/facebook-marketplace-scraper). TikTok Creative Center top ads are [TikTok Ads Scraper](https://apify.com/crawloop/tiktok-ads-scraper).

### Key features

- Keyword search and exact advertiser Page ID search
- Pasted Ad Library URLs keep that URL's country and filters
- Active, inactive, or both, plus political, housing, employment, and credit slices
- Image, video, meme, or text-only media filter
- Days running, variant count (`collationCount`), and an `isScaled` flag when an ad has two or more collated variants
- About 30 ads from the first page; raise `maxAds` to paginate, up to 1,000 per query
- JSON dataset for Python, Node.js, cURL, and MCP

### Input

| Field | Required | Default | What it does |
| :--- | :--- | :--- | :--- |
| `queries` | yes | `nike` | Keyword, numeric Page ID, or Ad Library URL. One search per entry. |
| `country` | no | `US` | ISO country when the query is not a full URL. |
| `activeStatus` | no | `active` | `active`, `inactive`, or `all`. |
| `adType` | no | `all` | `all`, `political`, `housing`, `employment`, or `credit`. |
| `mediaType` | no | `all` | `all`, `image`, `video`, `meme`, or `none`. |
| `maxAds` | no | `30` | Cap per query. Values above 30 paginate. |
| `proxyConfiguration` | no | Apify datacenter | On by default. The library often returns an empty page without a proxy. Use residential if pagination stops early. |

```json
{
  "queries": ["nike", "89516513179"],
  "country": "US",
  "activeStatus": "active",
  "mediaType": "all",
  "maxAds": 50
}
```

A full Ad Library URL is also a query. Put it in the JSON array as text; the Actor reads `country`, `q`, and `view_all_page_id` from it.

### Output

One dataset row per ad.

| Field | Meaning |
| :--- | :--- |
| `adArchiveId` | Ad Library id |
| `pageName`, `pageId`, `pageLikeCount` | Advertiser page |
| `bodyText`, `title`, `linkDescription` | Primary copy |
| `ctaText`, `ctaType` | Button label and type |
| `linkUrl` | Landing URL shown on the ad |
| `displayFormat` | `VIDEO`, `IMAGE`, `DCO`, `CAROUSEL`, and similar |
| `imageUrls`, `videoUrls` | Creative media URLs |
| `publisherPlatforms` | `FACEBOOK`, `INSTAGRAM`, `MESSENGER`, and others |
| `isActive` | Still running |
| `collationCount`, `isScaled` | How many variants share a collation; scaled when count is 2 or more |
| `startDate`, `endDate`, `daysRunning` | Delivery window and days from the start date |
| `spendLower`, `spendUpper`, `impressionsText` | Present when the Ad Library discloses them (often political or EU ads) |
| `country`, `query` | Search that produced the row |
| `adLibraryUrl` | Ad Library link for that ad id |
| `scrapedAt` | UTC timestamp |

```json
{
  "adArchiveId": "925321173274919",
  "pageName": "Nordstrom Rack",
  "pageId": "89516513179",
  "bodyText": "Buy online and pick up in store for free! Get up to 70% off Nike.",
  "ctaText": "Learn more",
  "displayFormat": "VIDEO",
  "publisherPlatforms": ["FACEBOOK", "INSTAGRAM", "MESSENGER"],
  "isActive": true,
  "collationCount": 2,
  "isScaled": true,
  "daysRunning": 51,
  "startDate": "2026-08-03",
  "country": "US",
  "query": "nike"
}
```

### Use cases

- Pull every active ad for a competitor keyword in the US, then sort by `daysRunning` to see what they kept on.
- Pass a Page ID on a schedule and diff `adArchiveId` values to spot new creatives.
- Filter `isScaled` rows when you only want ads the advertiser is running in more than one variant.
- Export landing URLs and CTAs into a sheet for a creative review.

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/facebook-ads-library-scraper').call({
  queries: ['nike'],
  country: 'US',
  maxAds: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].pageName, items[0].daysRunning);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token="YOUR_APIFY_TOKEN")
run = client.actor("crawloop/facebook-ads-library-scraper").call(run_input={
    "queries": ["nike"],
    "country": "US",
    "maxAds": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["pageName"], item["daysRunning"], item["linkUrl"])
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~facebook-ads-library-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries":["nike"],"country":"US","maxAds":30}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp). Connect your Apify account, then call `crawloop/facebook-ads-library-scraper`.

Example prompts:

- "Run Facebook Ads Library Scraper for the keyword nike in the US and return the 20 ads with the highest daysRunning."
- "Scrape active video ads for Page ID 89516513179 and list page name, CTA, and landing URL."
- "Find Facebook Ads Library ads for the query adidas in DE and summarize which creatives look scaled."
- "Chain Facebook Ads Library Scraper then TikTok Ads Scraper for nike and compare Meta days-running with TikTok top-ad CTR."

### Suite next step

After the Meta Ad Library export, run [TikTok Ads Scraper](https://apify.com/crawloop/tiktok-ads-scraper) for the same brand to collect Creative Center top ads, CTR score, video URL, and landing page. For Marketplace classifieds instead of ads, use [Facebook Marketplace Scraper](https://apify.com/crawloop/facebook-marketplace-scraper).

### Related Actors

- Facebook Ads Library Scraper ◄── you are here
- [TikTok Ads Scraper](https://apify.com/crawloop/tiktok-ads-scraper) — Creative Center top ads, CTR, video, landing page
- [Facebook Marketplace Scraper](https://apify.com/crawloop/facebook-marketplace-scraper) — Marketplace listings, not the Ad Library

### FAQ

**Does this need a Facebook login or a Meta developer token?**\
No. It reads the public Ad Library while logged out.

**Why do some ads have no spend or impressions?**\
The Ad Library shows spend and reach ranges mainly for political ads and for ads delivered in the EU. Commercial US ads often leave those fields empty. Days running and variant count are still filled.

**The run saved about 30 ads and then failed.**\
Pagination past the first page can be rate limited on a datacenter IP. Switch the proxy group to residential and rerun with the same `maxAds`.

**Can I monitor new ads?**\
Run the same Page ID on a schedule and compare `adArchiveId` to the previous dataset. This Actor does not keep a private diff store.

**Is this Facebook Marketplace?**\
No. Marketplace listings are a different product. Use [Facebook Marketplace Scraper](https://apify.com/crawloop/facebook-marketplace-scraper) for those. This Actor is only the Ads Library.

# Actor input Schema

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

One search per line. A word or phrase searches ad copy. A numeric Page ID returns that advertiser's ads. A full Ad Library URL keeps the country and filters from the URL.

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

ISO country code used when the query is not a full Ad Library URL. Example: US, GB, DE.

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

Which ads to include.

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

All ads, or a special-category slice.

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

Filter by creative format.

## `maxAds` (type: `integer`):

Stop each query after this many ads. The first page holds about 30 ads. Higher values paginate.

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

Datacenter proxy is on by default. The Ads Library often returns an empty page from the platform IP. Switch to residential if a run past 30 ads is rate limited.

## Actor input object example

```json
{
  "queries": [
    "nike"
  ],
  "country": "US",
  "activeStatus": "active",
  "adType": "all",
  "mediaType": "all",
  "maxAds": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Default dataset items.

# 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"
    ],
    "country": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/facebook-ads-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"],
    "country": "US",
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/facebook-ads-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"
  ],
  "country": "US"
}' |
apify call crawloop/facebook-ads-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/facebook-ads-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/Vm7I1TEyC9VSU8Gth/builds/aDdWvsTV1MZNUDgYO/openapi.json
