# Meta Ad Library Spy — Winning & Scaled Facebook Ads | $4/1K (`bovi/meta-ads-library-scraper`) Actor

Find competitors' WINNING ads, not just ads: is\_scaled flags creatives Meta runs in 3+ variants (the advertiser is spending), plus days\_active & longevity\_score — the signals ad-spy tools charge $99/mo for. Full creatives, CTAs, landing pages. Token-free official Ad Library source. Pay per ad.

- **URL**: https://apify.com/bovi/meta-ads-library-scraper.md
- **Developed by:** [Vitalii Bondarev](https://apify.com/bovi) (community)
- **Categories:** Marketing, Social media, MCP servers
- **Stats:** 5 total users, 4 monthly users, 91.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.88 / 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/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 Spy — Winning & Scaled Facebook Ads | $4/1K | No Token, No Login

Built for media buyers, ad researchers and growth hackers who don't just want competitors' ads — they want their **WINNING** ads. Every record carries `is_scaled` (Meta grouped 3+ near-duplicate variants → the advertiser is actively spending on it), `collation_count`, `days_active` and `longevity_score`: the exact signals ad-spy SaaS charges $99+/mo for, leading every row.

**Pricing: $4.00 per 1,000 ads.** No monthly fees, no token, pay only for delivered ads.

Scrape the [Meta Ad Library](https://www.facebook.com/ads/library) (formerly the Facebook Ad Library) **token-free** — no Meta account, no Graph API token, no government-ID verification. Search active and inactive ads by **keyword** or by **advertiser page ID** across any country, and get a clean, flat record per ad: creative copy, headline, call-to-action, destination link, publisher platforms (Facebook, Instagram, Messenger, Audience Network), delivery dates, active status, and **inline image and video creative URLs**. Pay per ad.

### Pricing example

**$4.00 per 1,000 ads.** 100 ads = $0.40. 1,000 ads = $4.00. 5,000 ads across 5 countries = $20.00. No per-run fee. No Meta account needed.

### Sample output

```json
{
  "ad_archive_id": "1234567890123456",
  "page_name": "Nike",
  "page_id": "15087023",
  "ad_creative_bodies": ["Just Do It. Shop the new Air Max 2026."],
  "cta_text": "Shop Now",
  "link_url": "https://www.nike.com/air-max-2026",
  "publisher_platforms": ["FACEBOOK", "INSTAGRAM"],
  "display_format": "image",
  "is_active": true,
  "ad_delivery_start_date": "2026-05-01",
  "days_active": 35,
  "collation_count": 12,
  "is_scaled": true,
  "media_count": 3,
  "ad_snapshot_url": "https://www.facebook.com/ads/library/?id=1234567890123456",
  "parse_confidence": 1.0,
  "scraped_at": "2026-06-05T09:00:00Z"
}
````

### Meta Ad Library Scraper

This **Meta Ad Library scraper** reads the same public data the Ad Library website serves to any visitor — the internal search results behind `facebook.com/ads/library`. Because it never touches the official Graph API, your buyers skip the entire onboarding wall: no Meta developer app, no ID verification, no token to generate or rotate. Point it at a keyword or an advertiser and it streams ads in real time.

### Facebook ads data you get per ad

| Field | Description |
|---|---|
| `ad_archive_id` | Unique Ad Library ID |
| `ad_snapshot_url` | Direct link to the ad in the Ad Library |
| `page_id` / `page_name` | Advertiser page ID and name |
| `page_profile_uri` / `page_profile_picture_url` / `page_like_count` | Advertiser profile, avatar, audience size |
| `byline` | "Paid for by" / advertiser disclaimer line |
| `ad_creative_bodies` | Ad body text(s) |
| `ad_creative_link_titles` | Headline/link title(s) |
| `ad_creative_link_descriptions` | Link description(s) |
| `cta_text` / `cta_type` | Call-to-action button |
| `link_url` | Destination URL |
| `display_format` | Image / video / carousel / DCO |
| `snapshot_images` | Image creative URLs (inline) |
| `snapshot_videos` | Video creative URLs (inline) |
| `media_count` | Count of inline creative URLs (images + videos) |
| `publisher_platforms` | FACEBOOK / INSTAGRAM / MESSENGER / AUDIENCE\_NETWORK / THREADS |
| `ad_delivery_start_date` / `ad_delivery_stop_date` | Run dates |
| `is_active` / `days_active` / `longevity_score` | Delivery longevity |
| `collation_count` / `collation_id` / `is_scaled` | Variant count + a scaled-winner flag |
| `spend_*` / `impressions_*` / `reach_estimate` | Ranges (political/issue ads only) |
| `categories` / `entity_type` / `contains_sensitive_content` / `state_media_run_label` | Classification & trust signals |
| `regional_regulation_data` | EU DSA transparency disclosures |
| `parse_confidence` / `warnings` | Data-quality signal |

### How to scrape Facebook ads by keyword or advertiser

1. Enter one or more **search terms** (e.g. `nike`, `weight loss`) and/or **advertiser page IDs**.
2. Pick **countries** (ISO codes; the Ad Library requires a country, default `US`).
3. Optionally filter by **ad type**, **active status**, and **media type**.
4. Set **max ads per search** to control cost, then run.

```json
{
  "searchTerms": ["nike"],
  "countries": ["US"],
  "adType": "all",
  "maxResults": 100
}
```

### Use cases for Meta Ad Library data

- **Find winning creatives fast** — sort by `is_scaled` / `collation_count` (how many variants an advertiser is running) and `days_active` to spot the ads a competitor is actually putting budget behind.
- **Competitor ad monitoring** — track which creatives a brand is running and for how long.
- **Ad creative research / swipe files** — pull winning ad copy, hooks, and inline media URLs at scale.
- **Lead generation** — surface advertisers in a niche by keyword and capture their landing pages.
- **Market & trend analysis** — measure ad longevity (`days_active`) as a proxy for what's working.
- **Political ad transparency** — for `political_and_issue_ads`, capture spend, impressions, and EU disclosures.

### Why this Facebook Ad Library scraper is reliable

- **Token-free** — no Meta login, no ID verification; your buyers run it with zero setup.
- **Inline media URLs** — image and video creative links (including every carousel card) come with the data; no per-ad render. Many scrapers hand you only the snapshot URL.
- **Self-healing pagination** — Meta rotates its internal `doc_id` roughly monthly, which silently breaks most Ad Library scrapers at page 2. This actor **re-extracts the live `doc_id` from each page it loads**, so pagination keeps working across rotations with no update and no downtime. You can still pin a `docId` manually if you ever want to.
- **Scale signal** — `collation_count` / `is_scaled` tell you how many variants of a creative an advertiser is running, so you can rank by what's actually getting budget — not just what exists.
- **Resilient parsing** — anchors on stable JSON field names, not CSS classes, and emits `parse_confidence` so structural changes surface loudly instead of shipping blanks.
- **Honest metrics** — spend/impressions are returned only when Meta actually publishes them (political/issue ads); commercial ads get `null`, never fabricated numbers.
- **Apify Proxy only** — uses the standard residential proxy configuration billed to the run owner; no external proxy account required.

### Frequently asked questions

**Do I need a Facebook account or Meta token?** No. This scraper uses the public Ad Library that any visitor can browse. No login, no Graph API token, no ID verification.

**Do I get ad spend and impressions?** Spend, impressions, and reach are published by Meta only for **political and issue ads**. Set `adType` to `political_and_issue_ads` to capture them. Commercial ads return copy, media, platforms, and dates — but no reliable spend (we return `null` rather than fabricating numbers).

**Why is a residential proxy recommended?** Meta blocks datacenter IPs. On the Apify cloud, enable an Apify **RESIDENTIAL** proxy in the proxy configuration (billed to the run owner) for reliable token-free scraping at volume.

**Can I scrape all ads from one advertiser?** Yes — add the advertiser's numeric `pageIds`.

**What happens when Meta changes its internal pagination ID?** Nothing on your end. Meta rotates the persisted-query `doc_id` behind the Ad Library every few weeks, which is what quietly breaks many scrapers after page 1. This actor reads the current `doc_id` straight out of the page on every run, so it self-heals through rotations. (Advanced: you can still override it via the `docId` input.)

**How do I find the best-performing ads?** Meta doesn't publish engagement for commercial ads, so use the proxies that it does expose: `days_active` (how long an ad has run) and `collation_count` / `is_scaled` (how many variants an advertiser is running). Long-running, heavily-collated creatives are the ones getting budget.

### Winning ad detection workflow

Sort by `days_active DESC, collation_count DESC` → ads running longest with most variants = what's actually getting budget. No spend data needed for commercial ads — longevity + variant count are the reliable proxies.

### EU DSA transparency data

The `regional_regulation_data` and `state_media_run_label` fields contain EU Digital Services Act transparency disclosures. Market separately to EU compliance and research teams — this is mandatory public data that Meta must expose.

### Use with AI Agents (MCP)

This Meta Ad Library scraper is callable as a **tool by AI agents** (Claude Desktop, Cursor, VS Code, n8n, or any MCP-compatible client) via Apify's hosted Model Context Protocol server.

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

### Integrations

Built for ad researchers, growth hackers, and competitive-intel teams mining Facebook and Instagram creatives at scale — the JSON/dataset output drops into the tools you already run, no glue code:

- **n8n / Make / Zapier** — trigger a run or pipe every new dataset item into 500+ apps (Google Sheets, Airtable, Slack, HubSpot, your database) with no code: [n8n](https://docs.apify.com/platform/integrations/n8n), [Make](https://docs.apify.com/platform/integrations/make), [Zapier](https://docs.apify.com/platform/integrations/zapier).
- **Webhooks** — fire your own endpoint the moment a run finishes, to push results straight into your pipeline ([docs](https://docs.apify.com/platform/integrations/webhooks)).
- **MCP server** — expose this actor as a tool to Claude, Cursor, or any [MCP client](https://mcp.apify.com) so an AI agent can pull this data mid-conversation ([guide](https://blog.apify.com/how-to-use-mcp/)).
- **API & SDKs** — fetch the dataset as JSON, CSV, or Excel through the Apify REST API or the Python / JS SDKs.

See all [Apify integrations](https://apify.com/integrations).

### Disclaimer

The Meta Ad Library is a public transparency tool. This actor accesses the same publicly available data any visitor can view, without logging in. Respect Meta's terms and applicable law when using the data.

### More scrapers from our toolkit

Building a data pipeline? These actors pair well with this one — each runs on your own Apify account with the same pay-per-result pricing, no subscription:

- [Ambitionbox Reviews Scraper](https://apify.com/bovi/ambitionbox-reviews-scraper)
- [Indeed Employer Intelligence](https://apify.com/bovi/indeed-employer-intelligence)
- [Saas Pricing Monitor](https://apify.com/bovi/saas-pricing-monitor)

Chain any of them together from the **Integrations** tab (the *Run succeeded* trigger) to build a multi-step workflow — one actor's output feeds the next.

### Use it from your existing tools

#### Use with Claude Desktop / Cursor / Cline (MCP)

Load this actor as a tool in your AI assistant. Call it directly from your AI assistant via the Apify MCP server — no Store browsing needed. Paste this into your MCP client config (e.g. `claude_desktop_config.json`) and restart the client:

```json
{
  "mcpServers": {
    "apify-meta-ads-library-scraper": {
      "command": "npx",
      "args": [
        "-y",
        "@apify/actors-mcp-server",
        "--tools",
        "bovi/meta-ads-library-scraper"
      ],
      "env": {
        "APIFY_TOKEN": "YOUR_APIFY_TOKEN"
      }
    }
  }
}
```

Replace `YOUR_APIFY_TOKEN` with your own Apify API token (free at apify.com → Settings → Integrations). Curated to a handful of tools so the agent selects reliably.

#### Works with Clay

Run this actor as an HTTP enrichment step inside a Clay table:

- **Method:** `POST`
- **URL:** `https://api.apify.com/v2/acts/bovi~meta-ads-library-scraper/run-sync-get-dataset-items?token={{apify_token}}`
- **Body (JSON):** map your Clay columns to the actor input (see the Input section above), e.g. `{"searchTerms": "{{clay_column}}"}`

The run finishes synchronously and returns the dataset rows straight into your Clay table. It runs on Apify's cloud under your own token and usage. Synchronous runs must complete within 300 seconds.

# Actor input Schema

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

Keywords to search ads for (e.g. 'nike', 'weight loss', 'crypto'). Each term runs as a separate query across every country. Leave empty if you only want advertiser page IDs.

## `pageIds` (type: `array`):

Numeric Facebook page IDs to pull ALL ads from a specific advertiser. Find a page ID in the Ad Library: open an advertiser and copy the numeric id from the URL. Works alongside or instead of search terms.

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

Two-letter ISO country codes (e.g. US, GB, DE). The Ad Library requires a country; each is searched separately. Default: US.

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

all = commercial + everything; political\_and\_issue\_ads = only political/issue ads, which additionally carry spend & impressions ranges.

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

Filter ads by whether they are currently running. 'all' returns both active and inactive ads.

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

Filter by creative format. 'all' keeps every format (image, video, carousel, text).

## `matchType` (type: `string`):

broad = ads containing the words in any order; exact = the exact phrase. Applies to search-term queries only.

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

Maximum ads to return per search term / page ID per country. The actor paginates automatically. Default 100. Keep low to control cost.

## `pageSize` (type: `integer`):

How many ads to push per batch for real-time output. Lower = faster first results; higher = fewer dataset writes.

## `docId` (type: `string`):

Meta's persisted-query id for the Ad Library pagination query. LEAVE EMPTY: the actor self-heals by re-extracting the live doc\_id from each page, so it survives Meta's ~monthly rotation automatically. Only set this to force a specific id (overrides self-healing).

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

Apify Proxy. RECOMMENDED on the cloud: Meta blocks datacenter IPs, so enable a RESIDENTIAL group for token-free scraping at volume. Billed to the run owner — no external proxy account needed.

## Actor input object example

```json
{
  "searchTerms": [
    "nike",
    "adidas"
  ],
  "countries": [
    "US"
  ],
  "adType": "all",
  "activeStatus": "all",
  "mediaType": "all",
  "matchType": "broad",
  "maxResults": 100,
  "pageSize": 25,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Dataset containing Meta Ads Library Scraper records (page\_name, is\_scaled, collation\_count, days\_active, is\_active, cta\_text, ad\_archive\_id, publisher\_platforms, ad\_delivery\_start\_date, link\_url, ad\_snapshot\_url, parse\_confidence).

# 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"
    ],
    "countries": [
        "US"
    ],
    "maxResults": 100,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("bovi/meta-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 = {
    "searchTerms": ["nike"],
    "countries": ["US"],
    "maxResults": 100,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("bovi/meta-ads-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"
  ],
  "countries": [
    "US"
  ],
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call bovi/meta-ads-library-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Meta Ad Library Spy — Winning & Scaled Facebook Ads | $4/1K",
        "description": "Find competitors' WINNING ads, not just ads: is_scaled flags creatives Meta runs in 3+ variants (the advertiser is spending), plus days_active & longevity_score — the signals ad-spy tools charge $99/mo for. Full creatives, CTAs, landing pages. Token-free official Ad Library source. Pay per ad.",
        "version": "0.1",
        "x-build-id": "cqDUWSTaqbCVEldJC"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/bovi~meta-ads-library-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-bovi-meta-ads-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/bovi~meta-ads-library-scraper/runs": {
            "post": {
                "operationId": "runs-sync-bovi-meta-ads-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/bovi~meta-ads-library-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-bovi-meta-ads-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",
                        "type": "array",
                        "description": "Keywords to search ads for (e.g. 'nike', 'weight loss', 'crypto'). Each term runs as a separate query across every country. Leave empty if you only want advertiser page IDs.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "pageIds": {
                        "title": "Advertiser page IDs",
                        "type": "array",
                        "description": "Numeric Facebook page IDs to pull ALL ads from a specific advertiser. Find a page ID in the Ad Library: open an advertiser and copy the numeric id from the URL. Works alongside or instead of search terms.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "countries": {
                        "title": "Countries (ISO codes)",
                        "type": "array",
                        "description": "Two-letter ISO country codes (e.g. US, GB, DE). The Ad Library requires a country; each is searched separately. Default: US.",
                        "default": [
                            "US"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "adType": {
                        "title": "Ad type / category",
                        "enum": [
                            "all",
                            "political_and_issue_ads"
                        ],
                        "type": "string",
                        "description": "all = commercial + everything; political_and_issue_ads = only political/issue ads, which additionally carry spend & impressions ranges.",
                        "default": "all"
                    },
                    "activeStatus": {
                        "title": "Active status",
                        "enum": [
                            "all",
                            "active",
                            "inactive"
                        ],
                        "type": "string",
                        "description": "Filter ads by whether they are currently running. 'all' returns both active and inactive ads.",
                        "default": "all"
                    },
                    "mediaType": {
                        "title": "Media type",
                        "enum": [
                            "all",
                            "image",
                            "video",
                            "meme",
                            "none"
                        ],
                        "type": "string",
                        "description": "Filter by creative format. 'all' keeps every format (image, video, carousel, text).",
                        "default": "all"
                    },
                    "matchType": {
                        "title": "Keyword match type",
                        "enum": [
                            "broad",
                            "exact"
                        ],
                        "type": "string",
                        "description": "broad = ads containing the words in any order; exact = the exact phrase. Applies to search-term queries only.",
                        "default": "broad"
                    },
                    "maxResults": {
                        "title": "Max ads per search",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum ads to return per search term / page ID per country. The actor paginates automatically. Default 100. Keep low to control cost.",
                        "default": 100
                    },
                    "pageSize": {
                        "title": "Streaming batch size",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "How many ads to push per batch for real-time output. Lower = faster first results; higher = fewer dataset writes.",
                        "default": 25
                    },
                    "docId": {
                        "title": "Pagination doc_id (advanced — leave empty)",
                        "type": "string",
                        "description": "Meta's persisted-query id for the Ad Library pagination query. LEAVE EMPTY: the actor self-heals by re-extracting the live doc_id from each page, so it survives Meta's ~monthly rotation automatically. Only set this to force a specific id (overrides self-healing)."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify Proxy. RECOMMENDED on the cloud: Meta blocks datacenter IPs, so enable a RESIDENTIAL group for token-free scraping at volume. Billed to the run owner — no external proxy account needed.",
                        "default": {
                            "useApifyProxy": 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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
