# Facebook Ads Library Scraper | EU Reach, Targeting & Alerts (`corvuslab/facebook-ads-library-scraper`) Actor

Scrape the Facebook / Meta Ads Library by keyword, advertiser page or link in 100+ countries. Get ad copy, creatives, platforms, days running, EU & UK reach by country, age and gender, targeting, payer, Instagram followers and political spend. New-ad alerts. No login.

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

## Pricing

from $0.55 / 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?

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

### What does Facebook Ads Library Scraper do?

Facebook Ads Library Scraper pulls ads out of the **Meta Ad Library**, the public archive of every ad on Facebook, Instagram, Messenger, Threads, WhatsApp and the Audience Network. Each ad comes back with **80 structured fields**: copy, creatives, platforms and days running, plus the **transparency data** Meta publishes for European ads, on by default — **EU reach by country, age and gender**, **UK reach by age and gender**, the targeted audience, the **payer and beneficiary**, and the advertiser's profile. It's no-code and exports to JSON, CSV, Excel, the API or an AI agent.

Give it **keywords**, **advertiser pages** (`facebook.com/nike` or a page ID) or **links pasted from the Ad Library**, in one country or many, and schedule it to get only new or changed ads.

> New to Apify? Sign up free and use the included monthly platform credit to try this Actor — no credit card needed.

**Why this scraper**

- ⚡ **Fast & low-cost** — lightweight and quick, so large runs stay cheap.
- 🧾 **Rich, typed records** — 80 fields per ad, with reach and spend as numbers rather than text.
- 🔓 **No login** — no Facebook account, cookies or API token.
- 🔔 **Alerts built in** — new ads straight to Telegram, Slack, Discord or any webhook.

Researching Google ads too? Our [Google Ads Scraper — Ads Transparency Center](https://apify.com/corvuslab/google-ads-transparency-scraper) gives you the same view of Google: ad copy, per-country reach by Google surface, and the advertiser's verified legal identity.

***

### What data can you extract from the Facebook Ads Library?

Every record carries **80 fields** grouped like this:

| Group | What you get |
|---|---|
| **Ad creative & copy** | Ad ID and link, headline, ad text, call to action (text + type), landing page, link caption & description, image URLs, video URLs & thumbnails, carousel cards and card count, format (image / video / carousel / dynamic), version group and number of versions |
| **Delivery & status** | Active flag, start date, end date, **days running**, platforms, special ad categories, AI-generated-media and sensitive-content flags |
| **EU & UK transparency** | **EU total reach**, reach **by country**, **by age** and **by gender**, the full **country × age × gender** table, **UK total reach** with its **age and gender** split, targeted age min/max, gender, targeted and excluded locations, **payer** and **beneficiary** |
| **Political & issue ads** | "Paid for by" disclaimer, spend range as text **plus numeric lower/upper bounds**, currency, **audience shares by age, gender and region**, the page's **total political spend** and spend by payer |
| **Advertiser intelligence** | Page name, ID, link, logo, cover photo, username, page likes, categories, page type, **verification status**, about text, **Instagram username, followers and verified flag**, **verified advertiser legal name, website and country**, link to all of the page's ads |
| **Run context & monitoring** | Keyword and country that found the ad, input link, scrape time, transparency-fetched flag, content fingerprint, `changeType` (NEW / UPDATED / UNCHANGED / EXPIRED), first-seen date |

***

### Key features

- 🔎 **Three ways to search** — keywords, advertiser pages or pasted Ad Library links in one run. Vanity links like `facebook.com/nike` are resolved for you.
- 🇪🇺 **EU & UK transparency by default** — reach, targeted audience, payer & beneficiary and the advertiser's verification and Instagram profile, with nothing to toggle.
- 🌍 **Multi-country in one run** — 100+ countries; each search runs once per country and every ad still appears once.
- 🎚️ **Library-side filters** — status, ad category (political, housing, employment, credit, financial), media type, platform, ad language, exact phrase and a shown-between window.
- 🆕 **True "launched after" filter** — keeps only ads that *started* on or after a date, unlike the library's own date filter.
- 🗳️ **Political ads, fully unpacked** — audience by age, gender and region, spend ranges as numeric bounds, and the page's political spend by payer.
- ♻️ **Monitoring that pays for itself** — only NEW and UPDATED ads are returned and billed, plus an optional stopped-ads report.

***

### 🚀 How to scrape the Facebook Ads Library

1. Enter **keywords** (e.g. `running shoes`), **advertiser pages** (e.g. `https://www.facebook.com/nike`), or paste an **Ad Library link**.
2. Pick **countries**, an **ad status** and any other filters, then set **Max ads per search**.
3. Leave **Add transparency details** on for reach, audience, payer and the advertiser profile.
4. (Optional) Turn on **Only new and changed ads** and a notification channel, then **Schedule** it.
5. Click **Start** and download the ads as **JSON, CSV or Excel**, or pull them from the **API**.

Run it with an empty input and it returns 50 sample ads for "nike" in the US, so you can see the output straight away.

#### Quick-start example input

```json
{
  "searchQueries": ["running shoes"],
  "countries": ["DE", "FR", "GB"],
  "activeStatus": "active",
  "maxResults": 100
}
```

This returns up to 100 live "running shoes" ads from each of Germany, France and the UK (300 in about two minutes). German and French ads arrive with EU reach by country, age and gender and who paid for them, UK ads with UK reach by age and gender, and all of them with the targeted audience.

***

### Input

Configure it in the visual editor with no code, or pass JSON through the API. There are **31 inputs** in six groups that match the editor.

#### 🔎 What to search

| Field | Type | What it does |
|---|---|---|
| `searchQueries` | array | Keywords to find in ads, such as a brand, product or topic. Each keyword is its own search. |
| `pageUrls` | array | Advertiser page links (`https://www.facebook.com/nike`) or numeric page IDs. |
| `startUrls` | array | Results links pasted from facebook.com/ads/library with your filters intact. A single-ad link (`…/ads/library/?id=…`) returns that one ad. |
| `maxResults` | integer | Ads to return **per** keyword, advertiser or link, and per country (default 50; 0 = everything the library lists). |

#### 🎚️ Filters

| Field | Type | What it does |
|---|---|---|
| `countries` | array | Where the ads were shown: 100+ countries or `ALL` (the default). Several countries = one search per country, de-duplicated. |
| `activeStatus` | enum | `active` (default), `inactive` (stopped ads) or `all`. |
| `adType` | enum | `all`, `political_and_issue_ads`, `housing_ads`, `employment_ads`, `credit_ads`, `financial_products_and_services_ads`. |
| `mediaType` | enum | `all`, `image`, `video`, `meme`, `image_and_meme`, `none`. |
| `publisherPlatforms` | array | `facebook`, `instagram`, `audience_network`, `messenger`, `threads`, `whatsapp`. Empty = all. |
| `searchType` | enum | `keyword_unordered` (all words, any order) or `keyword_exact_phrase`. |
| `contentLanguages` | array | Two-letter ad language codes, e.g. `en`, `de`, `es`. |
| `dateFrom` / `dateTo` | string | Ads shown within this window: `2026-10-01` or relative (`7 days`). |
| `onlyAdsNewerThan` | string | Keep only ads that **launched** on or after this day (`2026-10-01` or `30 days`). |

#### 📄 Output

| Field | Type | What it does |
|---|---|---|
| `includeDetails` | boolean | **On by default.** Adds EU & UK reach, targeted audience, payer & beneficiary and the advertiser profile. |
| `compact` | boolean | Core fields only: advertiser, dates, platforms, copy, link, media, EU reach. |
| `excludeEmptyFields` | boolean | Drop fields with no value instead of returning `null`. |

#### ♻️ Monitoring

| Field | Type | What it does |
|---|---|---|
| `incrementalMode` | boolean | Return only NEW ads and ones whose copy or status changed since the last run. |
| `stateKey` | string | Optional monitor name. Runs with the same name share a memory; blank = derived from the search. |
| `emitUnchanged` | boolean | Also return unchanged ads, marked `UNCHANGED` (these are charged). |
| `emitExpired` | boolean | Return an `EXPIRED` row for each ad from the last run that no longer appears. |

#### 🔔 Notifications

Credentials are secret inputs: encrypted, masked and never written to the log.

| Field | Type | What it does |
|---|---|---|
| `telegramToken` + `telegramChatId` | string | Telegram bot token + chat or channel ID. |
| `slackWebhookUrl` / `discordWebhookUrl` | string | Incoming webhook URL. |
| `webhookUrl` + `webhookHeaders` | string / object | POST the new ads as JSON to n8n, Make, Zapier or your own backend. |
| `notificationLimit` | integer | How many ads each message lists (1–20, default 5). |

#### ⚙️ Advanced

| Field | Type | What it does |
|---|---|---|
| `proxyConfiguration` | object | Keep the preselected setting; it keeps long searches reliable. |
| `detailConcurrency` | integer | How many ads' transparency details are read at once (1–10, default 4). |
| `maxRequestRetries` | integer | Retries per page before a search is given up (1–8, default 3). |

#### More example inputs

Political and issue ads in Germany launched in the last 30 days, with spend and audience:

```json
{
  "searchQueries": ["Bundestag"],
  "countries": ["DE"],
  "adType": "political_and_issue_ads",
  "onlyAdsNewerThan": "30 days",
  "maxResults": 500
}
```

A daily monitor that posts only new video ads to Slack and reports the ones that stopped:

```json
{
  "searchQueries": ["meal kit"],
  "countries": ["GB", "IE"],
  "mediaType": "video",
  "maxResults": 0,
  "incrementalMode": true,
  "emitExpired": true,
  "slackWebhookUrl": "https://hooks.slack.com/services/..."
}
```

***

### Output

Each dataset item is one ad. Here's a real record (trimmed; media URLs, cards and the full breakdown tables are left out):

```json
{
  "id": "955201527245300",
  "adUrl": "https://www.facebook.com/ads/library/?id=955201527245300",
  "pageId": "1691843657706928",
  "pageName": "Gadgets",
  "pageLikeCount": 3514436,
  "isActive": true,
  "startDate": "2026-05-12",
  "endDate": "2026-11-01",
  "daysRunning": 173,
  "publisherPlatforms": ["facebook", "instagram"],
  "displayFormat": "DPA",
  "title": "Jazz Dance Shoes for Women — Vibrant Colors & Versatile Fit",
  "linkUrl": "http://play.google.com/store/apps/details?id=com.dhgate.buyermob",
  "ctaText": "Shop now",
  "cardsCount": 6,
  "pageVerification": "NOT_VERIFIED",
  "instagramUsername": "dhgate_gadget",
  "instagramFollowers": 509944,
  "payer": "Meetsocial",
  "beneficiary": "世纪富轩科技发展（北京）有限公司",
  "euTotalReach": 748032,
  "euReachByCountry": { "RO": 171710, "PT": 138203, "GR": 70389, "BG": 65623 },
  "euReachByAge": { "35-44": 216723, "25-34": 176695, "45-54": 174882, "55-64": 104007 },
  "euReachByGender": { "male": 443554, "female": 333382, "unknown": 5519 },
  "targetAgeMin": 18,
  "targetAgeMax": 65,
  "ukTotalReach": 41930,
  "ukReachByGender": { "male": 18448, "female": 22714, "unknown": 291 },
  "searchQuery": "shoes",
  "scrapedAt": "2026-11-01T21:54:34.797188+00:00",
  "detailFetched": true
}
```

#### Data fields

- **Always included**: the ad, its copy and creative, delivery dates, platforms, page likes and categories, special categories, and the political spend range.
- **With `includeDetails`** (default): EU & UK reach and breakdowns, targeted audience, payer & beneficiary, the advertiser profile, and political audience shares and page spend.
- **With `incrementalMode`**: `changeType` and `firstSeenAt`.

Missing values come back as `null`; **compact mode** keeps only the core fields, and **`excludeEmptyFields`** drops empty ones. The Output tab also has an **Overview** table of the key columns.

***

### ♻️ How to monitor the Facebook Ads Library with incremental mode

Turn on **Only new and changed ads** and each run returns only **NEW** ads and **UPDATED** ones (copy, format or active status changed). Unchanged ads are recognised *before* their details are fetched, so they cost neither time nor money, and catalogue ads that rotate their product aren't flagged as UPDATED for that alone.

| | First run (baseline) | Next run (nothing changed) |
|---|---|---|
| Ads found | all | all |
| Transparency details fetched | all | **none** |
| Records returned & billed | all | **none** |

After the baseline, your cost depends on how much the advertisers change, not on how many ads you watch:

| Daily churn | of 1,000 tracked | billable records | you save |
|---|---|---|---|
| 5 % | 1,000 | 50 | **95 %** |
| 15 % | 1,000 | 150 | **85 %** |
| 30 % | 1,000 | 300 | **70 %** |

#### Setting up scheduled monitoring

1. Configure your keywords or advertiser pages, countries and filters.
2. Set **Max ads per search** to `0` so every run reads the whole search. Only a complete read can tell which ads stopped.
3. Turn on **Only new and changed ads**, and optionally **Report stopped ads**.
4. Run it once to set the baseline, then add a recurring run in the **Schedules** tab.

***

### 🔔 How to set up Facebook Ads Library alerts

Get pinged when a competitor launches a new ad. Fill in only the channels you want:

| Channel | What to configure |
|---|---|
| ✈️ **Telegram** | `telegramToken` (from @BotFather) + `telegramChatId` |
| 💬 **Slack** | `slackWebhookUrl` (Incoming Webhook URL) |
| 🎮 **Discord** | `discordWebhookUrl` (channel webhook URL) |
| 🪝 **Webhook** | `webhookUrl` receives the new ads as JSON; add `webhookHeaders` for auth. Works with n8n / Make / Zapier. |

Each message lists up to `notificationLimit` ads with the advertiser, headline, text and link. Channels fire independently, and with incremental mode on, alerts cover only new or changed ads.

***

### 💡 What can you do with Facebook Ads Library data?

#### Competitor ad monitoring

Watch every ad a rival runs across all six Meta platforms and get alerted the day a campaign launches or stops. Days running signals a winner: nobody keeps paying for creative that doesn't convert.

#### Creative research and swipe files

Collect headlines, copy, calls to action, carousel cards, images and videos for any keyword or category, then sort by days running to build a swipe file of proven creative.

#### Audience and reach intelligence

For ads shown in the EU or UK, see how many people an ad reached and how that splits by country, age and gender, next to the audience the advertiser targeted — without access to their ad account.

#### Political ad transparency and journalism

Track issue, election and political ads with their "paid for by" disclaimer, spend range and who saw them. Each page's political spend, split by payer, shows who funds a campaign.

#### Lead generation for agencies

Find businesses actively spending on Meta ads in your niche and country, with page likes, Instagram followers and verified website. Active advertisers are warm leads.

***

### 💰 How much does it cost to scrape the Facebook Ads Library?

This Actor uses Apify's **pay-per-event** model: a small fee when a run starts, plus a fee for each ad returned. The current numbers are on the **Pricing** tab. It runs without a browser, which keeps the per-ad fee at the low end of the market even with transparency details included. Two things cut your bill further:

- **Library-side filters**: ads you filtered out by country, status, category, media, platform, language or date are never fetched or billed.
- **Incremental mode**: after the baseline you pay only for new and changed ads.

***

### 🔌 Integrations & export

Export to **JSON, CSV, Excel** or an HTML table, or pull the data from the **REST API** and the **JavaScript / Python** clients. Run it on a **schedule**, connect it to **Google Sheets, Slack, Make, Zapier and n8n**, or use it as an **MCP tool** for AI agents.

***

### 🔗 Using the API

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

run_input = {
    "pageUrls": ["https://www.facebook.com/nike"],
    "countries": ["DE", "FR"],
    "activeStatus": "active",
    "maxResults": 100,
}

run = client.actor("corvuslab/facebook-ads-library-scraper").call(run_input=run_input)

for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(ad["pageName"], ad["daysRunning"], ad.get("euTotalReach"), ad["adUrl"])
```

***

### ❓ FAQ

**Why are reach, targeting and payer empty on some ads?** Meta publishes this data only for ads **shown in the EU or the UK**. EU ads get reach by country, age and gender plus the payer and beneficiary; UK ads get `ukTotalReach` with its age and gender split, but no payer. Ads that ran only elsewhere have none of it, so those fields are `null`.

**Why are spend and audience shares empty on most ads?** The library publishes spend only for **issue, election and political ads**, and only as a range ("€15K – €20K"); you get the text, numeric bounds and currency, plus audience shares by age, gender and region. Set `adType` to `political_and_issue_ads` to get them. For commercial ads, `euTotalReach` is the best measure of size.

**Why are Instagram followers or the verified legal name missing for some advertisers?** Instagram fields need a linked Instagram account, and the verified name, website and country appear only where Meta shows a verified identity.

**How many ads can I get?** `maxResults` applies **per** keyword, advertiser or link and per country (0 = everything listed), up to 20,000 ads per run. A run that nears its timeout stops by itself and keeps what it found, so raise the timeout under Run options for very large jobs.

**What's the difference between "Shown from" and "Only ads launched after"?** "Shown from" (`dateFrom`) matches ads *shown* in that window, including old ads still running. "Only ads launched after" (`onlyAdsNewerThan`) keeps only ads that started on or after your date. The library has no newest-first order, so this filter reads about the first 1,000 ads of each search; pair it with narrow keywords or a country.

**Why does a keyword return ads that don't contain it?** The library matches loosely: some ads match without the keyword in their visible text, and common words (`no such thing`) can match thousands of unrelated ads. **Exact phrase** narrows it; distinctive brand or product names work best.

**Why do image and video links stop working after a while?** They point to Facebook's own servers and expire. Download the creatives you want to keep soon after the run.

**When does the stopped-ads report appear?** EXPIRED rows appear only on runs that read the whole search (`maxResults` 0, or a limit the search doesn't reach), so a capped run never reports false stops. Each EXPIRED row counts as a result.

***

### ⚖️ Is it legal to scrape the Facebook Ads Library?

Meta publishes the Ad Library openly so that anyone can see who is advertising and to whom. This Actor collects only that **publicly available** data and needs no login. You're responsible for how you use it, in particular any personal information such as the names on political disclaimers, and for complying with Meta's terms and applicable law, including the GDPR where it applies. Not affiliated with, endorsed by or sponsored by Meta Platforms, Inc., Facebook or Instagram.

***

**Keywords:** facebook ads library scraper · facebook ad library scraper · meta ad library scraper · facebook ads library api · instagram ads scraper · meta ads scraper · facebook competitor ads · competitor ad monitoring · EU ad reach data · ad transparency data · political ads scraper · facebook ad spy tool · ad creative research · days running winning ads · lead generation · export to CSV · export to Excel · no-code scraper · MCP tool for AI agents

# Changelog

This Actor's version history is a separate document: https://apify.com/corvuslab/facebook-ads-library-scraper/changelog.md

# Actor input Schema

## `searchQueries` (type: `array`):

Words to find in ads, for example a brand, product or topic. Each keyword is its own search; ads found by several keywords are returned once.

## `pageUrls` (type: `array`):

Facebook page links (https://www.facebook.com/nike) or numeric page IDs. Returns the ads that page runs in the selected countries.

## `startUrls` (type: `array`):

Paste results links straight from facebook.com/ads/library, with the filters you set there. A single-ad link (…/ads/library/?id=…) returns that one ad.

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

How many ads to return for each keyword, advertiser or link. 0 = everything the library lists.

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

Where the ads were shown. Pick several to run each search once per country (each ad is still returned once).

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

Running ads, stopped ads, or both.

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

Special ad categories. Political and issue ads also carry spend ranges and audience shares.

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

Only ads with this kind of creative.

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

Only ads shown on these platforms. Leave empty for all.

## `searchType` (type: `string`):

How keywords are matched against the ad text.

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

Two-letter language codes, for example en, de, es. Leave empty for all languages.

## `dateFrom` (type: `string`):

Ads that were shown on or after this day: 2026-10-01, or a relative '7 days'.

## `dateTo` (type: `string`):

Ads that were shown on or before this day.

## `onlyAdsNewerThan` (type: `string`):

Keep only ads whose start date is on or after this day: 2026-10-01, or '30 days'. Unlike 'Shown from', ads launched earlier are left out even if they are still running.

## `includeDetails` (type: `boolean`):

Adds each ad's EU and UK reach (by country, age and gender), targeted age, gender and locations, the payer and beneficiary, and the advertiser's profile (verification, Instagram followers, about text). Reach and audience exist for ads shown in the EU or UK.

## `compact` (type: `boolean`):

Return only the core fields: advertiser, dates, platforms, ad copy, link, media and EU reach. Handy for AI agents and spreadsheets.

## `excludeEmptyFields` (type: `boolean`):

Drop fields that have no value instead of returning them as null.

## `incrementalMode` (type: `boolean`):

Remember the ads seen on earlier runs of this search and return only NEW ads and ones whose copy or status changed (see changeType).

## `stateKey` (type: `string`):

Optional name for this monitor's memory. Runs with the same name share it; leave empty to derive it from the search.

## `emitUnchanged` (type: `boolean`):

Also return ads that have not changed, marked UNCHANGED (these are charged).

## `emitExpired` (type: `boolean`):

Return a short EXPIRED row for each ad from the last run that no longer appears, for example an ad the advertiser switched off. Only on runs that read the whole search; each row counts as a result.

## `telegramToken` (type: `string`):

From @BotFather.

## `telegramChatId` (type: `string`):

The chat or channel to post to.

## `slackWebhookUrl` (type: `string`):

An incoming-webhook URL.

## `discordWebhookUrl` (type: `string`):

A channel webhook URL.

## `webhookUrl` (type: `string`):

Receives a JSON POST with the new ads.

## `webhookHeaders` (type: `object`):

Extra headers for the webhook, for example an Authorization header.

## `notificationLimit` (type: `integer`):

How many ads each message lists.

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

Keep the preselected setting: it is what keeps long searches reliable.

## `detailConcurrency` (type: `integer`):

How many transparency panels to read at once.

## `maxRequestRetries` (type: `integer`):

Retries per page before a search is given up.

## Actor input object example

```json
{
  "searchQueries": [
    "running shoes"
  ],
  "maxResults": 50,
  "countries": [
    "ALL"
  ],
  "activeStatus": "active",
  "adType": "all",
  "mediaType": "all",
  "searchType": "keyword_unordered",
  "includeDetails": true,
  "compact": false,
  "excludeEmptyFields": false,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "notificationLimit": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "detailConcurrency": 4,
  "maxRequestRetries": 3
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `allItems` (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 = {
    "searchQueries": [
        "running shoes"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("corvuslab/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 = { "searchQueries": ["running shoes"] }

# Run the Actor and wait for it to finish
run = client.actor("corvuslab/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 '{
  "searchQueries": [
    "running shoes"
  ]
}' |
apify call corvuslab/facebook-ads-library-scraper --silent --output-dataset

```

## MCP server setup

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