# Facebook Ad Library Scraper Pro (`constructive_calm/facebook-ad-library-pro`) Actor

Scrape Facebook Ads Library by keyword, page URL, or advertiser name. Returns full creative + CTA + linkUrl + advertiser identity + active dates. 35% cheaper than the leading alternative. No login required, country dropdown, multi-platform/media filters, resume checkpoints.

- **URL**: https://apify.com/constructive\_calm/facebook-ad-library-pro.md
- **Developed by:** [Omar Eldeeb](https://apify.com/constructive_calm) (community)
- **Categories:** Social media, Lead generation, E-commerce
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

Pay per event

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 Pro — Keyword + Page + Advertiser Search

Scrape **Facebook's public Ad Library** — every ad currently or recently running across Facebook, Instagram, Messenger, and Audience Network. Search by keyword, by page URL, or by advertiser name. Get CTA text, link URLs, full creative (image/video), advertiser info, and active dates.

**$0.49 per 1,000 ads — 35% cheaper than the leading competitor.** First 10 ads of every run are free.

> No Facebook login required. No developer-app approval. Works on commercial ads, not just political. Country dropdown with 50+ ISO codes. Resume checkpoints save your run mid-flight.

### What does Facebook Ad Library Scraper Pro do?

It pulls structured data from `facebook.com/ads/library` — the public archive of every ad Meta has run on Facebook, Instagram, Messenger, WhatsApp, Threads, and the Audience Network. Unlike the [official Meta Ad Library API](https://www.facebook.com/ads/library/api/) (political/issue ads only, EU-only, no creative or link data), this actor returns full commercial ads with CTA, link URLs, body text, creatives, and advertiser identity.

Built for marketers, competitive intel analysts, agencies, and researchers who need the same insights Meta surfaces in the Ad Library UI — but at scale, in JSON/CSV/Excel.

### Why use Facebook Ad Library Scraper Pro?

- **Cheapest in its class — $0.49 per 1,000 ads.** First 10 every run are free. Compare: leading competitor charges $0.75/1K.
- **Three input modes in one actor.** Paste Ad Library search URLs, raw Facebook page URLs (vanity or `profile.php?id=...`), or just type a `keyword` / `advertiserName` and we'll build the right URL for you.
- **Country dropdown with names, not codes.** Pick "United States (US)" instead of typing `us` or `US` and hoping. Or use the Custom country code field for any of the 240+ ISO-3166 codes.
- **Multi-platform + media-type filters as first-class fields.** Filter by FACEBOOK / INSTAGRAM / MESSENGER / AUDIENCE_NETWORK / THREADS / WHATSAPP and image / video / meme / text-only.
- **CSV-ready output.** Every creative URL, CTA, link, and advertiser field is emitted as a flat column (`linkUrl`, `ctaText`, `imageUrl1..5`, `videoUrl1`) — your Sheets import just works. Nested objects preserved for power users.
- **Dedup'd advertiser About cache.** Resolve an advertiser's verified status, categories, and profile pic *once per page* across the whole run — not once per ad. Saves you money on bulk page scrapes.
- **Resume checkpoints.** Crashed run? Restart it within 6 hours with the same input — we resume from the last cursor instead of re-charging you for already-scraped ads.
- **EU reach + AAA targeting (optional).** Toggle on `Scrape ad details` to get demographic reach (age × gender × country) and AAA audience metadata for any ad.
- **Residential proxy built-in.** Default proxy config rotates per request, avoiding the CAPTCHA traps that kill datacenter scrapes.

### How to use Facebook Ad Library Scraper Pro

1. Open the Apify Console and click **Try for free**.
2. Pick a search style — fastest is to type a **Keyword** (e.g., `nike`) or **Advertiser name** (e.g., `Spotify`) and pick a **Country**.
3. Or paste **URLs** — Ad Library search URLs (`https://www.facebook.com/ads/library/?...`) or raw Facebook page URLs (`https://www.facebook.com/ZapierApp`). One per line.
4. Set **Total ads cap** (across the whole run) and/or **Limit per input URL** to control spend.
5. (Optional) Enable **Scrape ad details** for EU reach, **Resolve advertiser About** for page-level verification + categories.
6. Click **Save & Start**. First 10 ads are free.
7. When the run finishes, export the dataset as **JSON, CSV, or Excel** from the Storage tab.

### Input examples

**Keyword search (cheapest, fastest):**
```json
{
  "keyword": "nike",
  "country": "US",
  "mediaType": "video",
  "count": 500
}
````

**Page URL — vanity slug:**

```json
{
  "urls": ["https://www.facebook.com/ZapierApp"],
  "limitPerSource": 200
}
```

**Multiple pages + global cap:**

```json
{
  "urls": [
    "https://www.facebook.com/ZapierApp",
    "https://www.facebook.com/Spotify",
    "https://www.facebook.com/airbnb"
  ],
  "count": 1000,
  "resolveAdvertiser": true
}
```

**Advertiser-name search across all of Europe with date filter:**

```json
{
  "advertiserName": "Adidas",
  "country": "DE",
  "period": "last30d",
  "mediaType": "video",
  "platforms": ["FACEBOOK", "INSTAGRAM"]
}
```

**Migrating from the leading competitor — paste their input shape, we accept it:**

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

### Output

Sample row:

```json
{
  "adArchiveId": "1234567890123456",
  "adId": "987654321",
  "pageId": "20531316728",
  "pageName": "Nike",
  "isActive": true,
  "startDate": 1709251200,
  "endDate": null,
  "totalActiveTime": 4320000,
  "publisherPlatform": ["FACEBOOK", "INSTAGRAM"],
  "country": "US",
  "currency": "USD",
  "displayFormat": "VIDEO",
  "title": "Just Do It.",
  "bodyText": "Run with the new Air Zoom Pegasus 41. Built for breakthroughs.",
  "linkDescription": "Free shipping on orders $50+",
  "ctaText": "Shop Now",
  "ctaType": "SHOP_NOW",
  "linkUrl": "https://nike.com/w/pegasus-41",
  "imageUrl1": "https://scontent.xx.fbcdn.net/v/t39.../creative1.jpg",
  "videoUrl1": "https://video.xx.fbcdn.net/v/t39.../ad-hd.mp4",
  "videoPreviewImageUrl1": "https://scontent.xx.fbcdn.net/v/t39.../preview.jpg",
  "pageVerified": true,
  "pageCategories": ["Sportswear store"],
  "pageProfilePictureUrl": "https://scontent.xx.fbcdn.net/v/t39.../profile.jpg",
  "snapshot": { "...full Facebook payload preserved here..." },
  "runTag": "weekly-pull-2026-05",
  "sourceUrl": "https://www.facebook.com/ads/library/?...&q=nike",
  "scrapedAt": "2026-05-18T14:23:11.482Z"
}
```

**Data fields:**

| Field | Type | Description |
|---|---|---|
| `adArchiveId` | string | Unique Ad Library archive ID — primary key. |
| `adId` | string | Internal Meta ad ID. |
| `pageId` / `pageName` | string | Advertiser identity. |
| `isActive` | boolean | Whether the ad is still running. |
| `startDate` / `endDate` | unix epoch | Start / stop timestamps. |
| `totalActiveTime` | integer | Seconds the ad has been running. |
| `publisherPlatform` | array | Where the ad runs: FACEBOOK / INSTAGRAM / MESSENGER / AUDIENCE\_NETWORK / THREADS / WHATSAPP. |
| `country` | string | ISO country code the ad targets. |
| `displayFormat` | string | IMAGE / VIDEO / CAROUSEL / DCO / etc. |
| `title` / `bodyText` / `linkDescription` | string | Ad copy. |
| `ctaText` / `ctaType` | string | Call-to-action button (`Shop Now`, `SHOP_NOW`). |
| `linkUrl` | string | Destination URL of the ad. |
| `imageUrl1..5`, `videoUrl1`, `videoPreviewImageUrl1` | string | Creative CDN URLs, flat. |
| `spendLowerBound` / `spendUpperBound` / `spendCurrency` | number/string | Political/social-issue ads only. |
| `impressionsLowerBound` / `impressionsUpperBound` | number | Political/social-issue ads only. |
| `pageVerified` | boolean | Blue-tick verification status. |
| `pageCategories` / `pageProfilePictureUrl` | array/string | Advertiser metadata. |
| `snapshot` | object | Full original Facebook payload — preserved for power users. |
| `advertiser` | object | Resolved About-page data (when `resolveAdvertiser=true`). |
| `demographicReach` | object | EU age × gender × country reach (when `scrapeAdDetails=true`). |
| `runTag` | string | Echoed from input — useful for joining datasets. |
| `sourceUrl` | string | Which input URL produced this row. |
| `scrapedAt` | ISO 8601 | When we captured the row. |

### How much does it cost to scrape Facebook Ad Library?

**Pay-per-event pricing — only pay for what you get.**

| Event | Price | When it fires |
|---|---|---|
| `ad-scraped` | **$0.00049** ($0.49 / 1,000) | Once per ad extracted with creative, CTA, link, body text. |
| `ad-details-fetched` | **$0.00025** ($0.25 / 1,000) | Only when `scrapeAdDetails=true` AND Meta returns non-empty data. EU reach + AAA targeting metadata. Note: per Meta's policy, full demographic reach is only exposed for political/social-issue ads. Commercial ads typically return empty — we don't charge for those empty calls. |
| `advertiser-resolved` | **$0.001** ($1 / 1,000 unique pages) | Only when `resolveAdvertiser=true` — fired ONCE per page across the whole run, not per ad. |

**First 10 events of every run are free.** Cancel anytime.

**Typical run costs:**

| Run | Ads | Details | Advertisers | **Cost** |
|---|---|---|---|---|
| Sample run (free trial) | 10 | — | — | **$0.00** |
| Small competitive scan | 500 | — | — | **$0.20** |
| 1K-ad market sweep | 1,000 | — | 20 pages | **$0.49 + $0.02 = $0.51** |
| 10K-ad campaign analysis | 10,000 | — | 200 pages | **$4.90 + $0.20 = $5.10** |
| 10K with EU reach details | 10,000 | 10,000 | 200 pages | **$4.90 + $2.50 + $0.20 = $7.60** |
| 100K-ad agency audit | 100,000 | — | 2,000 pages | **$49 + $2 = $51** |

Compare: the leading competitor charges $0.75/1K with no dedup'd advertiser cache — the 10K + advertiser run above would cost you **$7.50 + $7.50 = $15** there. We're 66% cheaper on that workload.

### Tips & advanced options

- **`country=ALL`** returns ads from every country Meta indexes. Be cautious — the result count can explode for popular keywords.
- **`mediaType=video`** is one of the highest-signal filters for competitive intel — high-spend advertisers ship video creative.
- **`platforms`** filter is exact-match. Setting `["FACEBOOK", "INSTAGRAM"]` excludes ads that only run on Messenger or Audience Network.
- **`period=last7d`** + `sortBy=most_recent` is the fastest way to surface brand-new ad pushes from a competitor.
- **`resolveAdvertiser=true`** + scraping multiple ads per page costs **almost nothing extra** — we fire the resolve event once per unique pageId, not per ad. Compare to competitors that re-fetch per ad.
- **Schedule it.** Use Apify Schedules to run weekly with `period=last7d` and a stable `runTag`, then JOIN datasets by `pageId` to track advertiser changes over time.
- **Chain into other actors.** Pipe the dataset into a Shopify, web-archive, or LLM-summarization actor for full competitive-intel pipelines.
- **Resume checkpoints.** Leave `enableCheckpoint=true` (the default). If the run crashes or you stop it manually, restart with the same input within 6 hours — we pick up from the last successful pagination cursor, no double-charge.

### Legal disclaimer

This actor only scrapes data that Facebook makes **publicly available** in its Ad Library — the same data anyone can see by visiting [facebook.com/ads/library](https://www.facebook.com/ads/library). No Facebook login is performed. No private user data is extracted.

Per Meta's [Ad Library Terms](https://www.facebook.com/business/help/2405092116183307), ads in the Ad Library are public. However, your jurisdiction's data-protection laws (GDPR, CCPA, etc.) may impose restrictions on how you process advertiser data. You are responsible for compliance with applicable laws in your use of the output.

If you scrape political/social-issue ads, note that some fields (spend range, impressions range, demographic breakdown) are only available for ads in that category — a Meta policy choice.

### FAQ & support

**Q: Does this work for commercial ads, or only political/issue ads?**
Yes — works for all ads in the public Ad Library. The official Meta API is restricted to political/issue ads; this actor is not.

**Q: Why is the leading competitor $0.75 and you're $0.49 — is the data the same?**
Same source (`facebook.com/ads/library`), same field coverage. We're cheaper because (a) newer cost structure, (b) we dedup advertiser-About calls per pageId instead of per-ad, (c) we extract the first page free from SSR HTML instead of paying for the GraphQL call.

**Q: My country isn't in the dropdown — what do I do?**
Use the **Custom country code** field underneath the dropdown. Type any 2-letter ISO-3166 code (e.g., `BD`, `PK`, `MA`, `JM`).

**Q: I'm getting fewer ads than expected.**
(1) Some ads are geo-fenced — try `country=ALL`. (2) `activeStatus=active` filters out ended ads — try `activeStatus=all`. (3) Facebook's pagination occasionally returns empty pages mid-run; our retry logic handles up to 2 consecutive empties before stopping that source.

**Q: Can I run this on a schedule?**
Yes. Use Apify Schedules + a stable `runTag` so you can join datasets across runs.

**Q: I'm migrating from another Ad Library scraper — will my old input still work?**
Yes. We accept the `scrapePageAds.period` / `scrapePageAds.activeStatus` / `scrapePageAds.sortBy` / `scrapePageAds.countryCode` dot-notation keys as aliases.

For issues: [open a ticket on Apify](https://apify.com/contact) or reach the maintainer through the Apify Store actor page.

# Actor input Schema

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

Paste Ad Library search URLs (https://www.facebook.com/ads/library/?...) or raw Facebook page URLs (https://www.facebook.com/ZapierApp). Auto-detected. Accepts both string arrays and curious\_coder-style \[{url: "..."}] shape for migration. Leave blank if using the Keyword or Advertiser name fields below.

## `keyword` (type: `string`):

Type a search term — we'll build the Ad Library search URL for you using the Country + Media type + Ad type filters below. Faster than hand-crafting `q=` params. Example: `nike`. Leave blank if using URLs above.

## `advertiserName` (type: `string`):

Search by advertiser name instead of keyword (search\_type=page). Returns ads from pages matching that name. Example: `Spotify`. Leave blank if using Keyword or URLs above.

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

Two-letter ISO country code. Only used when Keyword or Advertiser name is set, OR to override the country from a pasted URL. If your country isn't listed, use Custom country code below.

## `customCountryCode` (type: `string`):

Overrides the dropdown above. 2-letter ISO 3166-1 alpha-2 code (e.g., `BD` for Bangladesh, `PK` for Pakistan). Leave blank to use the dropdown.

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

Filter by creative format. Maps to the Ad Library `media_type=` URL parameter.

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

Filter by ad category. Political & social ads include extra fields (spend range, impressions range, demographic reach).

## `platforms` (type: `array`):

Filter ads by the platforms they run on. One per line: FACEBOOK, INSTAGRAM, MESSENGER, AUDIENCE\_NETWORK, THREADS, WHATSAPP. Leave blank for all.

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

Limit to ads ACTIVE in this window. Note: many ads run for months/years, so the `startDate` field in the output may show a date older than the window — that's the ad's original run-start date, not when it was indexed. For 'newly launched ads only', also set sortBy=most\_recent.

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

Filter by whether the ad is still running.

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

Result ordering. Defaults to highest-impressions-first (matches the Ad Library UI default).

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

Fire a second call per ad to fetch EU demographic reach (age × gender × country breakdown) and AAA targeting metadata. Per Meta's policy, full reach is only exposed for political/social-issue ads — commercial ads usually return empty. We only charge $0.25/1K when non-empty data comes back. Off by default.

## `resolveAdvertiser` (type: `boolean`):

Fetch each advertiser's public About page (verified status, categories, profile pic) — ONCE per page, regardless of how many ads they have. Costs $1 per 1,000 unique advertisers — much cheaper than competitors who refetch per ad.

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

Cap the number of ads scraped per input URL / keyword. Leave blank to scrape all available ads. Actual count may exceed by up to 30 (one extra paginated batch).

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

Hard ceiling on total ads emitted by this run. Overrides limitPerSource when reached. Leave blank for unlimited.

## `enableCheckpoint` (type: `boolean`):

Save progress every batch to the key-value store. If the run crashes or is restarted within 6 hours with the same input, resume from where it stopped instead of paying for already-scraped ads.

## `maxConcurrency` (type: `integer`):

Parallel paginations across input URLs. Facebook is sensitive to per-IP load — keep at 2-3 unless using high-rotation residential proxy.

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

Optional label echoed into every output row's `runTag` column. Useful for joining datasets from scheduled runs.

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

Residential proxy strongly recommended — datacenter IPs get CAPTCHA'd within tens of requests. Country override here will change the proxy egress (different from the ad-search country).

## Actor input object example

```json
{
  "urls": [
    "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"
  ],
  "country": "ALL",
  "mediaType": "all",
  "adType": "all",
  "period": "",
  "activeStatus": "all",
  "sortBy": "impressions_desc",
  "scrapeAdDetails": false,
  "resolveAdvertiser": false,
  "enableCheckpoint": true,
  "maxConcurrency": 2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Every ad captured from the Facebook Ad Library, with creative + CTA + link + advertiser fields. Download as JSON, CSV, or Excel.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("constructive_calm/facebook-ad-library-pro").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": ["https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"] }

# Run the Actor and wait for it to finish
run = client.actor("constructive_calm/facebook-ad-library-pro").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"
  ]
}' |
apify call constructive_calm/facebook-ad-library-pro --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Facebook Ad Library Scraper Pro",
        "description": "Scrape Facebook Ads Library by keyword, page URL, or advertiser name. Returns full creative + CTA + linkUrl + advertiser identity + active dates. 35% cheaper than the leading alternative. No login required, country dropdown, multi-platform/media filters, resume checkpoints.",
        "version": "0.2",
        "x-build-id": "Bat4D87EeNFk7HXJZ"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/constructive_calm~facebook-ad-library-pro/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-constructive_calm-facebook-ad-library-pro",
                "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/constructive_calm~facebook-ad-library-pro/runs": {
            "post": {
                "operationId": "runs-sync-constructive_calm-facebook-ad-library-pro",
                "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/constructive_calm~facebook-ad-library-pro/run-sync": {
            "post": {
                "operationId": "run-sync-constructive_calm-facebook-ad-library-pro",
                "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": {
                    "urls": {
                        "title": "🔗 URLs (search or page)",
                        "type": "array",
                        "description": "Paste Ad Library search URLs (https://www.facebook.com/ads/library/?...) or raw Facebook page URLs (https://www.facebook.com/ZapierApp). Auto-detected. Accepts both string arrays and curious_coder-style [{url: \"...\"}] shape for migration. Leave blank if using the Keyword or Advertiser name fields below.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "keyword": {
                        "title": "🔍 Keyword (auto-builds search URL)",
                        "type": "string",
                        "description": "Type a search term — we'll build the Ad Library search URL for you using the Country + Media type + Ad type filters below. Faster than hand-crafting `q=` params. Example: `nike`. Leave blank if using URLs above."
                    },
                    "advertiserName": {
                        "title": "🏷️ Advertiser name (auto-builds search URL)",
                        "type": "string",
                        "description": "Search by advertiser name instead of keyword (search_type=page). Returns ads from pages matching that name. Example: `Spotify`. Leave blank if using Keyword or URLs above."
                    },
                    "country": {
                        "title": "🌍 Country",
                        "enum": [
                            "ALL",
                            "US",
                            "GB",
                            "CA",
                            "AU",
                            "DE",
                            "FR",
                            "IT",
                            "ES",
                            "NL",
                            "SE",
                            "NO",
                            "DK",
                            "FI",
                            "IE",
                            "BE",
                            "AT",
                            "CH",
                            "PL",
                            "PT",
                            "GR",
                            "RO",
                            "CZ",
                            "HU",
                            "BR",
                            "MX",
                            "AR",
                            "CL",
                            "CO",
                            "IN",
                            "ID",
                            "PH",
                            "TH",
                            "VN",
                            "MY",
                            "SG",
                            "JP",
                            "KR",
                            "TW",
                            "HK",
                            "AE",
                            "SA",
                            "EG",
                            "IL",
                            "TR",
                            "ZA",
                            "NG",
                            "KE",
                            "GH",
                            "NZ",
                            "RU",
                            "UA"
                        ],
                        "type": "string",
                        "description": "Two-letter ISO country code. Only used when Keyword or Advertiser name is set, OR to override the country from a pasted URL. If your country isn't listed, use Custom country code below.",
                        "default": "ALL"
                    },
                    "customCountryCode": {
                        "title": "Custom country code (optional)",
                        "type": "string",
                        "description": "Overrides the dropdown above. 2-letter ISO 3166-1 alpha-2 code (e.g., `BD` for Bangladesh, `PK` for Pakistan). Leave blank to use the dropdown."
                    },
                    "mediaType": {
                        "title": "🖼️ Media type",
                        "enum": [
                            "all",
                            "image",
                            "video",
                            "meme",
                            "image_and_meme",
                            "none"
                        ],
                        "type": "string",
                        "description": "Filter by creative format. Maps to the Ad Library `media_type=` URL parameter.",
                        "default": "all"
                    },
                    "adType": {
                        "title": "📂 Ad category",
                        "enum": [
                            "all",
                            "political_and_issue_ads",
                            "housing_ads",
                            "employment_ads",
                            "credit_ads",
                            "financial_products_and_services_ads"
                        ],
                        "type": "string",
                        "description": "Filter by ad category. Political & social ads include extra fields (spend range, impressions range, demographic reach).",
                        "default": "all"
                    },
                    "platforms": {
                        "title": "📱 Publisher platforms",
                        "type": "array",
                        "description": "Filter ads by the platforms they run on. One per line: FACEBOOK, INSTAGRAM, MESSENGER, AUDIENCE_NETWORK, THREADS, WHATSAPP. Leave blank for all.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "period": {
                        "title": "🗓️ Date range",
                        "enum": [
                            "",
                            "last24h",
                            "last7d",
                            "last14d",
                            "last30d"
                        ],
                        "type": "string",
                        "description": "Limit to ads ACTIVE in this window. Note: many ads run for months/years, so the `startDate` field in the output may show a date older than the window — that's the ad's original run-start date, not when it was indexed. For 'newly launched ads only', also set sortBy=most_recent.",
                        "default": ""
                    },
                    "activeStatus": {
                        "title": "Active status",
                        "enum": [
                            "all",
                            "active",
                            "inactive"
                        ],
                        "type": "string",
                        "description": "Filter by whether the ad is still running.",
                        "default": "all"
                    },
                    "sortBy": {
                        "title": "Sort by",
                        "enum": [
                            "impressions_desc",
                            "most_recent"
                        ],
                        "type": "string",
                        "description": "Result ordering. Defaults to highest-impressions-first (matches the Ad Library UI default).",
                        "default": "impressions_desc"
                    },
                    "scrapeAdDetails": {
                        "title": "💎 Scrape ad details (EU reach + AAA)",
                        "type": "boolean",
                        "description": "Fire a second call per ad to fetch EU demographic reach (age × gender × country breakdown) and AAA targeting metadata. Per Meta's policy, full reach is only exposed for political/social-issue ads — commercial ads usually return empty. We only charge $0.25/1K when non-empty data comes back. Off by default.",
                        "default": false
                    },
                    "resolveAdvertiser": {
                        "title": "🏢 Resolve advertiser About page",
                        "type": "boolean",
                        "description": "Fetch each advertiser's public About page (verified status, categories, profile pic) — ONCE per page, regardless of how many ads they have. Costs $1 per 1,000 unique advertisers — much cheaper than competitors who refetch per ad.",
                        "default": false
                    },
                    "limitPerSource": {
                        "title": "#️⃣ Limit per input URL",
                        "minimum": 1,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "Cap the number of ads scraped per input URL / keyword. Leave blank to scrape all available ads. Actual count may exceed by up to 30 (one extra paginated batch)."
                    },
                    "count": {
                        "title": "#️⃣ Total ads cap (across all sources)",
                        "minimum": 1,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Hard ceiling on total ads emitted by this run. Overrides limitPerSource when reached. Leave blank for unlimited."
                    },
                    "enableCheckpoint": {
                        "title": "💾 Enable resume checkpoint",
                        "type": "boolean",
                        "description": "Save progress every batch to the key-value store. If the run crashes or is restarted within 6 hours with the same input, resume from where it stopped instead of paying for already-scraped ads.",
                        "default": true
                    },
                    "maxConcurrency": {
                        "title": "Concurrent fetches",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Parallel paginations across input URLs. Facebook is sensitive to per-IP load — keep at 2-3 unless using high-rotation residential proxy.",
                        "default": 2
                    },
                    "runTag": {
                        "title": "🏷️ Run tag",
                        "type": "string",
                        "description": "Optional label echoed into every output row's `runTag` column. Useful for joining datasets from scheduled runs."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy",
                        "type": "object",
                        "description": "Residential proxy strongly recommended — datacenter IPs get CAPTCHA'd within tens of requests. Country override here will change the proxy egress (different from the ad-search country).",
                        "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
