# Facebook Ad Library Scraper Monitoring Mode Meta Instagram Ads (`scrapesage/facebook-ad-library-scraper`) Actor

Scrape Facebook, Instagram & Meta ads from the public Meta Ad Library by keyword, Facebook Page, or URL. Get ad copy, creatives, videos, CTA, links, dates & advertiser data — 50+ fields per ad, no login. Monitoring mode returns only NEW ads since your last run. Export JSON, CSV or Excel.

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

## Pricing

$0.50 / 1,000 ad scrapeds

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

## Facebook Ad Library Scraper — Meta & Instagram Ads, No Login

Scrape **Facebook, Instagram & Meta ads** from the public **Meta Ad Library** by keyword, Facebook Page, or URL — ad copy, creatives, CTA, links, dates & advertiser data. No login or cookies.

Meta (formerly Facebook) runs **one** ad library for its whole network, so a single search covers ads across **Facebook, Instagram, Messenger, Threads, Audience Network and WhatsApp**. Type a brand or keyword, paste a Facebook Page, or drop a full Ad Library URL, and get back clean, structured rows for every ad: the creative text, all images and videos, the call-to-action, the destination link, run dates, the platforms it ran on, and the advertiser behind it.

> ⭐ **Unique feature — Monitoring mode:** run it on a schedule and get back **only the new ads since your last run.** Track exactly what a competitor newly launches, without wading through ads you've already seen. [Jump to Monitoring mode →](#-monitoring-mode--only-new-ads-since-last-run)

> **Not affiliated with Meta.** This is an independent tool that reads Meta's **public** Ad Library (the same data anyone can browse at facebook.com/ads/library). It collects business/advertiser information only — never personal contact details.

### What you can do with it

- **Competitor ad research** — pull every ad a brand is running and see their angles, offers, and creative.
- **Ad inspiration / swipe files** — collect winning creatives and copy across a whole niche by keyword.
- **Market & trend monitoring** — track which advertisers are live in a country and what they're pushing, and get alerted to new ads via Monitoring mode.
- **Political / issue ad transparency** — for those categories, capture the extra disclosures Meta provides (audience estimates, spend and reach where available).

### ⭐ Monitoring mode — only new ads since last run

Most scrapers re-download the same ads every run. Turn on **Monitoring mode** and this one remembers every ad it has returned before and gives you back **only the ads it hasn't seen** — perfect for a scheduled run that answers "what did this advertiser launch since yesterday?"

- The **first run** returns everything (your baseline).
- **Every run after** returns only the new ads — so a quiet day costs almost nothing and a launch day surfaces exactly the new creatives.
- Set a **Monitor ID** (e.g. `nike-us`) to keep one monitor stable even if you tweak filters, and to run several independent monitors side by side.

Pair it with Apify's scheduler for hands-off competitor alerts.

### Output

Each ad becomes one clean row. **50+ fields per ad** — we flatten every creative, link, and advertiser detail Meta exposes into clean columns, rather than dumping a raw blob.

Example record (abbreviated):

```json
{
  "adArchiveId": "1234567890123456",
  "adLibraryUrl": "https://www.facebook.com/ads/library/?id=1234567890123456",
  "pageName": "Nike",
  "pageId": "15087023444",
  "status": "ACTIVE",
  "startDate": "2026-03-17T00:00:00.000Z",
  "publisherPlatforms": ["FACEBOOK", "INSTAGRAM", "MESSENGER"],
  "displayFormat": "DPA",
  "bodyText": "Celebra tu cumpleaños con Nike y obtén acceso a productos exclusivos.",
  "ctaText": "Install now",
  "linkUrl": "https://www.nike.com/",
  "images": [],
  "videos": [],
  "cards": [{ "title": "Air Max", "linkUrl": "https://…", "imageUrl": "https://…" }]
}
````

**Full field list:** `recordType, id, sourceName, sourceUrl, scrapedAt, adArchiveId, adId, adLibraryUrl, adSnapshotUrl, pageId, pageName, pageProfileUri, pageProfilePictureUrl, pageLikeCount, pageCategories, pageVerified, pageEntityType, isActive, status, startDate, endDate, totalActiveTimeSeconds, collationCount, publisherPlatforms, displayFormat, currency, categories, countryIsoCode, title, bodyText, byline, caption, linkUrl, linkDescription, ctaText, ctaType, disclaimerLabel, brandedContentPartner, images, videos, cards, extraTexts, extraLinks, extraImages, extraVideos, containsSensitiveContent, containsDigitalCreatedMedia, spend, impressions, reachEstimate, estimatedAudienceSize, regionsReached, demographics, targetedOrReachedCountries, isPoliticalOrIssueAd, sourceInputType, sourceQuery`.

`spend`, `impressions`, `estimatedAudienceSize`, `regionsReached`, and `demographics` are populated **only** for transparency categories (political/issue, housing, employment, credit) — Meta doesn't publish them for ordinary commercial ads, so they're `null` there (expected, not an error). Results export as **JSON, CSV, or Excel**, or pull them via the Apify API.

### How to use

1. Click **Try for free** and open the actor.
2. Choose what to scrape — any combination:
   - **Search terms:** a keyword like `nike` or `electric scooter` (each runs as its own search).
   - **Facebook Page URLs or IDs:** `https://www.facebook.com/nike` or a numeric page ID — returns that advertiser's ads.
   - **Ad Library URLs:** paste a full `facebook.com/ads/library/?…` URL to keep any filter combination exactly.
3. *(Optional)* Set filters: country, active/inactive, ad category, media type, platforms, language, date range.
4. *(Optional)* Turn on **Monitoring mode** and set a **Monitor ID** to get only new ads on future runs.
5. Leave **Proxy** on **Residential** (required — see FAQ).
6. Set **Max ads** to cap the run.
7. Click **Start**. When it finishes, **Export** the dataset (JSON/CSV/Excel) or fetch it via the API.

### Input

| Field | What it does |
|---|---|
| **Search terms** | Keywords to search, e.g. `nike`, `electric scooter`. Each runs as its own search. |
| **Facebook Page URLs or IDs** | `https://www.facebook.com/nike` or a numeric page ID — returns that advertiser's ads. |
| **Ad Library URLs** | Paste a full `facebook.com/ads/library/?…` URL to preserve any filter combo exactly. |
| **Country** | One country, or **All countries**. |
| **Ad status** | Active, inactive, or both. |
| **Ad category** | All, or a transparency category (political/issue, housing, employment, credit). |
| **Media type** | All / image / video / meme / text. |
| **Platforms** | Facebook, Instagram, Messenger, Audience Network, Threads, WhatsApp. |
| **Languages** | Restrict to ad creative in chosen languages. |
| **Date range** | Ads that first ran on/after and on/before given dates. |
| **Max ads** | Total cap across all sources (`0` = unlimited). In monitoring mode, caps how many ads are *scanned* per run. |
| **Monitoring mode** | Return only ads not seen in a previous run. First run baselines; later runs return only new ads. |
| **Monitor ID** | Optional name tying runs into one monitor (e.g. `nike-us`). Runs sharing it share the memory of seen ads. |
| **Proxy** | **Residential, on by default — required** (Meta blocks datacenter IPs). |

Minimal input example:

```json
{
  "searchTerms": ["nike"],
  "country": "US",
  "adActiveStatus": "ACTIVE",
  "maxResults": 100,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

### How we compare

Most Ad Library scrapers return the easy subset (page name + ad text + one image). This actor also captures **all** images, **all** videos with HD/SD/preview URLs, **carousel cards**, extra creatives (additional images/videos/links/text), CTA text + type, advertiser byline, disclaimer label, branded-content partner, page like-count, verified status, page categories, ad-category tags, the ad's country, and the transparency fields for political ads — and it's the one with **Monitoring mode** for new-ad alerts.

### FAQ

- **Do I need a proxy?** Yes — **Residential proxy is required and on by default.** Meta blocks datacenter IPs at the network level, so the scraper reaches the Ad Library through Apify Residential proxy and rotates to a fresh residential IP automatically if Meta rate-limits one. Leave Proxy set to **Residential**; datacenter proxies will be blocked.
- **Do I need to log in?** No. It reads only the public Ad Library — no Facebook account, password, or cookies.
- **Exact page targeting:** a numeric page ID or `profile.php?id=…` targets a page exactly. A vanity slug (`facebook.com/nike`) falls back to an advertiser-name search — for exactness, paste the Ad Library "view all ads" URL into **Ad Library URLs**.
- **How does Monitoring mode know what's new?** It remembers the ad IDs it has returned before (per Monitor ID) and outputs only IDs it hasn't seen. Because the Ad Library is sorted by reach, a monitor catches new ads *within the set it scans* — for a single advertiser that's effectively complete; for a broad keyword, raise **Max ads** so a brand-new low-reach ad isn't missed.
- **Billing:** you're charged per ad returned to the dataset, so **Max ads** controls your spend (and in Monitoring mode you only pay for genuinely new ads). `0` means unlimited.
- **Empty results:** if a search returns nothing, the run still **succeeds** and the status message explains the likely reason (wrong country, active-only with no live ads, different ad language, etc.).
- **Is scraping the Ad Library legal?** The Ad Library is public and this tool collects business/advertiser data only — never personal contact details. Note your results can still contain personal data, which is protected by the GDPR in the EU and similar laws elsewhere; scrape personal data only with a legitimate reason, and consult a lawyer if unsure.

***

*Keywords: facebook ad library scraper, meta ad library scraper, meta ads scraper, facebook ads scraper, instagram ads scraper, scrape facebook ads, meta ad library api, facebook ads library, competitor ad research, ad spy tool.*

# Actor input Schema

## `searchTerms` (type: `array`):

Keywords to search the Ad Library for, e.g. "nike", "electric scooter". Each term runs as its own search. Leave empty if you only use Page URLs or Ad Library URLs.

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

Facebook page URLs (e.g. https://www.facebook.com/nike) or numeric page IDs. Returns ads run by that advertiser. A numeric ID or profile.php?id=… gives exact page targeting; a vanity slug falls back to an advertiser-name search.

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

Paste full Meta Ad Library URLs (https://www.facebook.com/ads/library/?...). Every filter encoded in the URL is preserved — the best way to target an exact page or a complex filter combination.

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

Country whose Ad Library to query. Use ALL to search every country at once. Accepts any ISO-3166 two-letter code via Ad Library URLs.

## `adActiveStatus` (type: `string`):

Return currently-running ads, stopped ads, or both.

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

ALL covers every public ad. The transparency categories surface extra disclosures (audience estimates, sometimes spend) for political/issue, housing, employment, and credit ads.

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

Restrict results by creative format.

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

Only include ads that ran on these Meta surfaces. Leave empty for all.

## `languages` (type: `array`):

Only include ads whose creative is in one of these languages. Leave empty for any.

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

Only include ads that first ran on or after this date.

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

Only include ads that first ran on or before this date.

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

Cap on total ads collected across every source. Set to 0 for unlimited (paginates until Meta returns no more). Each ad written is one billable result.

## `monitoringMode` (type: `boolean`):

When ON, the run remembers every ad it has returned before (per monitor) and outputs ONLY ads it has not seen in a previous run. Perfect for scheduled runs: "what new ads has this advertiser launched since I last checked?". The first run returns everything (the baseline); later runs return only new ads. In this mode, Max ads caps how many ads are SCANNED per run (cost control), not how many are output.

## `monitorId` (type: `string`):

Optional name that ties runs together into one monitor (e.g. "nike-us"). Runs sharing a Monitor ID share the same memory of seen ads. Leave blank to auto-derive one from your input — but set it explicitly if you want the monitor to survive small input changes, or to run several independent monitors.

## `pageDelaySeconds` (type: `integer`):

Seconds to wait between each pagination request. Meta rate-limits Ad Library pagination aggressively — if a run stops early with a rate-limit message, raise this (try 8–10). The first page of each search is unaffected. Higher = slower but more reliable for large pulls.

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

REQUIRED. Leave this on Residential. Meta blocks datacenter IPs at the TLS layer, so the scraper needs Apify Residential proxy to reach the Ad Library. The scraper rotates residential IPs automatically when Facebook rate-limits a given IP.

## Actor input object example

```json
{
  "searchTerms": [
    "nike"
  ],
  "country": "US",
  "adActiveStatus": "ALL",
  "adType": "ALL",
  "mediaType": "ALL",
  "publisherPlatforms": [],
  "languages": [],
  "maxResults": 100,
  "monitoringMode": false,
  "pageDelaySeconds": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

The dataset of scraped ads: creative text, all images & videos, CTA, links, advertiser details, dates, platforms, and transparency fields.

## `runSummary` (type: `string`):

Per-run counts and a plain-English status — explains why a run was empty, was rate-limited, or (in Monitoring mode) returned no new ads.

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

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

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/facebook-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 '{
  "searchTerms": [
    "nike"
  ],
  "country": "US",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call scrapesage/facebook-ad-library-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Facebook Ad Library Scraper Monitoring Mode Meta Instagram Ads",
        "description": "Scrape Facebook, Instagram & Meta ads from the public Meta Ad Library by keyword, Facebook Page, or URL. Get ad copy, creatives, videos, CTA, links, dates & advertiser data — 50+ fields per ad, no login. Monitoring mode returns only NEW ads since your last run. Export JSON, CSV or Excel.",
        "version": "0.1",
        "x-build-id": "60djGmnZJI7d51eer"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrapesage~facebook-ad-library-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrapesage-facebook-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/scrapesage~facebook-ad-library-scraper/runs": {
            "post": {
                "operationId": "runs-sync-scrapesage-facebook-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/scrapesage~facebook-ad-library-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-scrapesage-facebook-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",
                "properties": {
                    "searchTerms": {
                        "title": "Search terms (keywords)",
                        "type": "array",
                        "description": "Keywords to search the Ad Library for, e.g. \"nike\", \"electric scooter\". Each term runs as its own search. Leave empty if you only use Page URLs or Ad Library URLs.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "pageUrls": {
                        "title": "Facebook Page URLs or IDs",
                        "type": "array",
                        "description": "Facebook page URLs (e.g. https://www.facebook.com/nike) or numeric page IDs. Returns ads run by that advertiser. A numeric ID or profile.php?id=… gives exact page targeting; a vanity slug falls back to an advertiser-name search.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "startUrls": {
                        "title": "Ad Library URLs",
                        "type": "array",
                        "description": "Paste full Meta Ad Library URLs (https://www.facebook.com/ads/library/?...). Every filter encoded in the URL is preserved — the best way to target an exact page or a complex filter combination.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "country": {
                        "title": "Country",
                        "enum": [
                            "ALL",
                            "US",
                            "GB",
                            "CA",
                            "AU",
                            "IE",
                            "DE",
                            "FR",
                            "ES",
                            "IT",
                            "NL",
                            "SE",
                            "PL",
                            "PT",
                            "BR",
                            "MX",
                            "AR",
                            "IN",
                            "ID",
                            "PH",
                            "TH",
                            "VN",
                            "JP",
                            "KR",
                            "TR",
                            "AE",
                            "SA",
                            "ZA",
                            "NG",
                            "EG",
                            "NZ",
                            "BE",
                            "CH",
                            "AT",
                            "DK",
                            "NO",
                            "FI",
                            "GR",
                            "CZ",
                            "RO",
                            "HU"
                        ],
                        "type": "string",
                        "description": "Country whose Ad Library to query. Use ALL to search every country at once. Accepts any ISO-3166 two-letter code via Ad Library URLs.",
                        "default": "US"
                    },
                    "adActiveStatus": {
                        "title": "Ad status",
                        "enum": [
                            "ALL",
                            "ACTIVE",
                            "INACTIVE"
                        ],
                        "type": "string",
                        "description": "Return currently-running ads, stopped ads, or both.",
                        "default": "ALL"
                    },
                    "adType": {
                        "title": "Ad category",
                        "enum": [
                            "ALL",
                            "POLITICAL_AND_ISSUE_ADS",
                            "HOUSING_ADS",
                            "EMPLOYMENT_ADS",
                            "CREDIT_ADS"
                        ],
                        "type": "string",
                        "description": "ALL covers every public ad. The transparency categories surface extra disclosures (audience estimates, sometimes spend) for political/issue, housing, employment, and credit ads.",
                        "default": "ALL"
                    },
                    "mediaType": {
                        "title": "Media type",
                        "enum": [
                            "ALL",
                            "IMAGE",
                            "VIDEO",
                            "MEME",
                            "NONE"
                        ],
                        "type": "string",
                        "description": "Restrict results by creative format.",
                        "default": "ALL"
                    },
                    "publisherPlatforms": {
                        "title": "Platforms",
                        "type": "array",
                        "description": "Only include ads that ran on these Meta surfaces. Leave empty for all.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "FACEBOOK",
                                "INSTAGRAM",
                                "MESSENGER",
                                "AUDIENCE_NETWORK",
                                "THREADS",
                                "WHATSAPP"
                            ],
                            "enumTitles": [
                                "Facebook",
                                "Instagram",
                                "Messenger",
                                "Audience Network",
                                "Threads",
                                "WhatsApp"
                            ]
                        },
                        "default": []
                    },
                    "languages": {
                        "title": "Languages",
                        "type": "array",
                        "description": "Only include ads whose creative is in one of these languages. Leave empty for any.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "en",
                                "es",
                                "pt",
                                "fr",
                                "de",
                                "it",
                                "nl",
                                "pl",
                                "tr",
                                "ru",
                                "ar",
                                "he",
                                "ja",
                                "ko",
                                "zh",
                                "hi",
                                "id",
                                "th",
                                "vi"
                            ],
                            "enumTitles": [
                                "English",
                                "Spanish",
                                "Portuguese",
                                "French",
                                "German",
                                "Italian",
                                "Dutch",
                                "Polish",
                                "Turkish",
                                "Russian",
                                "Arabic",
                                "Hebrew",
                                "Japanese",
                                "Korean",
                                "Chinese",
                                "Hindi",
                                "Indonesian",
                                "Thai",
                                "Vietnamese"
                            ]
                        },
                        "default": []
                    },
                    "dateFrom": {
                        "title": "Started on or after",
                        "type": "string",
                        "description": "Only include ads that first ran on or after this date."
                    },
                    "dateTo": {
                        "title": "Started on or before",
                        "type": "string",
                        "description": "Only include ads that first ran on or before this date."
                    },
                    "maxResults": {
                        "title": "Max ads",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap on total ads collected across every source. Set to 0 for unlimited (paginates until Meta returns no more). Each ad written is one billable result.",
                        "default": 100
                    },
                    "monitoringMode": {
                        "title": "Monitoring mode — only NEW ads since last run",
                        "type": "boolean",
                        "description": "When ON, the run remembers every ad it has returned before (per monitor) and outputs ONLY ads it has not seen in a previous run. Perfect for scheduled runs: \"what new ads has this advertiser launched since I last checked?\". The first run returns everything (the baseline); later runs return only new ads. In this mode, Max ads caps how many ads are SCANNED per run (cost control), not how many are output.",
                        "default": false
                    },
                    "monitorId": {
                        "title": "Monitor ID (monitoring mode)",
                        "type": "string",
                        "description": "Optional name that ties runs together into one monitor (e.g. \"nike-us\"). Runs sharing a Monitor ID share the same memory of seen ads. Leave blank to auto-derive one from your input — but set it explicitly if you want the monitor to survive small input changes, or to run several independent monitors."
                    },
                    "pageDelaySeconds": {
                        "title": "Delay between pagination pages",
                        "minimum": 0,
                        "maximum": 60,
                        "type": "integer",
                        "description": "Seconds to wait between each pagination request. Meta rate-limits Ad Library pagination aggressively — if a run stops early with a rate-limit message, raise this (try 8–10). The first page of each search is unaffected. Higher = slower but more reliable for large pulls.",
                        "default": 3
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "REQUIRED. Leave this on Residential. Meta blocks datacenter IPs at the TLS layer, so the scraper needs Apify Residential proxy to reach the Ad Library. The scraper rotates residential IPs automatically when Facebook rate-limits a given IP.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
