# Facebook Ad Library Winning Ads Finder: AI creative breakdown (`rich_minds/fb-ad-library-winning-ads`) Actor

First 25 ads free. Facebook Ad Library winning ads: collapses variants, drops dead, political and seen ads, scores each Facebook and Instagram creative by days running, adds an AI hook, angle and offer. Pay per qualified ad. Free demo on any plan; live search runs on your own Apify account.

- **URL**: https://apify.com/rich\_minds/fb-ad-library-winning-ads.md
- **Developed by:** [Rich Minds](https://apify.com/rich_minds) (community)
- **Categories:** Social media, E-commerce, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 qualified ad (rules only)s

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

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

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

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

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

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

# README

## Facebook Ad Library Winning Ads Finder: AI creative breakdown

**Your competitors' longest-running Facebook ads — hook, offer and angle broken down, one row each.**

⚡ First **25 ads free** · 💵 **$0.003** per qualified ad · 🤖 **$0.012** with AI assessment · 🔑 **No API key needed** — the AI uses the model access of your Apify plan, or your own key · ⏱️ demo in 1 s; ~2 min for 150 scanned ads (estimate)

![One row per winning ad — winner score, tier, days running, variants, landing domain and the swipe-file line](https://api.apify.com/v2/key-value-stores/ibHh9UNYTUhWDIrWl/records/shortlist.svg)

> **Try it in 30 seconds.** Click **Try it** — the form is already filled with a working example (8 sample Ad Library
> records, free). Your first **25 qualified ads** are free, and ads that fail your filters are never charged.
> → [What a run costs](#-pricing--what-a-run-really-costs) · [What the AI adds](#-what-the-ai-tier-adds) · [Run it weekly](#-run-it-weekly) · [Swipe file in Google Sheets](#-swipe-file-in-google-sheets)

### ⚡ At a glance

| | |
|---|---|
| **What you get** | one row per winning creative: winner score 0–100, days running, offer, landing domain, hook — with AI also angle, evidence and a rewrite for your product; a summary per competitor and a report to forward |
| **You provide** | 1–10 search terms or competitor Facebook pages; optionally one sentence about your product |
| **Output** | JSON / CSV / Excel, best-first, plus the funnel in `OUTPUT` and a `DIGEST` for Slack / e-mail |
| **Typical run** | 3 terms × 50 ads = 150 scanned → ≈ 20–50 qualified (one qualified ad replaces 3–7 raw rows) |
| **Cost of that run** | ≈ $0.11 on the source + your first 25 ads free here, then $0.003 each ($0.012 with AI) |
| **AI tier, all in** | ≈ $0.015 per ad ($0.012 event + ≈ $0.003 AI tokens with the default model) |
| **Keys / setup** | none — the demo runs on any plan; the live search runs the source Store Actor on your Apify plan (else `sourceMode: dataset`) |
| **Works with** | Schedules, e-mail, Slack, webhooks, Google Sheets, Make / n8n / Zapier, MCP & AI agents |

### 🎯 What this Actor does

You pay only for the ads that pass your filters:

- **One row per creative** — it collapses variants (`variantCount`) and drops dead, political and seen ads free.
- **Which ads are winning** — it scores each creative 0–100 with reasons: days running, active, variants, placements.
- **The offer and the landing page** — discount, free shipping, price, bundle, urgency, the clean landing URL — and,
  with `enrichLandingPages`, the store and product behind it.
- **AI creative breakdown** — hook, angle, offer, CTA, audience with verbatim quotes, a fit score against *your*
  product and a rewrite of the angle for it.
- **A weekly monitor that reports changes** — new ads, alerts when an ad stops or passes 30 / 60 / 90 days, a
  summary per competitor and a report to forward to your client.

#### 🧭 Search the Meta Ad Library by keyword, page or URL

`searchTerms` in your `country`, `competitorPages` or `adLibraryUrls`; `mediaType`, `maxAdsToScan` and
`maxAdsPerSearch` bound the source bill, `OUTPUT.yieldByQuery` shows what each term paid.

#### 🏆 Winner score and free filters — the winning ads finder rule

`minWinnerScore` (40): days running ≤ 40 points, active 15, variants ≤ 20, 2+ placements 10, impressions ≤ 15.
`minDaysRunning`, `minVariants`, `platforms`, `landingDomainIncludes` / `landingDomainExcludes`, `excludeAdvertisers`,
`includePoliticalAds`, `adLanguage`, `targetFlags` and `suppressionList` drop ads before any charge.

#### 🛍️ Landing pages: store, product and price

`enrichLandingPages: true` reads each qualified ad's landing page: store platform, product, price, rating, reviews —
$0.004 per page that yields a store or product.

#### 🔔 Change alerts: stopped ads and confirmed winners

`changeAlerts: true`: one `rowType: alert` row when a competitor **stopped** an ad you have, or it passed **30 / 60 /
90 days** — in the Change alerts view, the digest and the webhook, $0.003 each. The free demo ends with one sample.

#### 📊 Competitor reports and a client-ready report

- **`advertiserReports: true`** — one `rowType: advertiser` row per top advertiser (≤ 10): active, new, stopped and
  30+-day ads, average days running, share of voice, top angles and offers ($0.02 each, *Competitor report* view).
- **Competitors to watch** — every search lists its top 10 advertisers by long-running ads in `OUTPUT` and the digest,
  with `OUTPUT.saveAsMonitor`: the ready input of a weekly monitor on them.
- **`REPORT`** — every run writes a client-ready HTML page (thumbnails, hooks, offers, AI breakdown) to forward;
  its link is `OUTPUT.reportUrl`. Free.

### 🆚 Why this instead of a Facebook Ad Library scraper?

| | [Facebook Ad Library Scraper (`curious_coder/facebook-ads-library-scraper`)](https://apify.com/curious_coder/facebook-ads-library-scraper) | **Facebook Ad Library Winning Ads Finder: AI creative breakdown** |
|---|---|---|
| **Price** | $0.00075 per result + $0.00005 per run start · 5,855 users / 30 days | from $0.003 per qualified ad, first 25 free, no start fee |
| **What you pay for** | every *row scraped* — each variant, dead, political and duplicate ad | only *qualified ads* — anything that fails your filters costs **$0** |
| **Same 100 winning ads, all in** | ≈ 700 raw rows: $0.53 here, then hours of sorting — or $4.06 on `apify/facebook-ads-scraper` (700 × $0.0058) | $0.83 basic (source $0.53 + 100 × $0.003) — ≈ 80 % less than the Apify route; $2.03 with AI, all in |
| **Landing-page details** | `apify/facebook-ads-scraper`: + $0.0057 per URL enriched | `enrichLandingPages`: $0.004 per page that yields a store or product |
| **Which ads work** | you sort by start date in a spreadsheet | winner score 0–100 with reasons, variants collapsed |
| **Hook / offer / angle** | raw copy only | offer on every row; AI breakdown with verbatim evidence |
| **Repeat runs** | the same ads again next week | only new ads delivered and charged, plus stopped / 30-60-90-day alerts |
| **Spend control** | `count` only | hard caps: `maxAdsToScan`, `maxQualified`, `maxDiscoveryChargeUsd` |

#### 💸 Cheaper than an ad spy tool seat — an AdSpy alternative

| | AdSpy / Minea-style spy tool | This Actor, weekly monitor of 10 competitors |
|---|---|---|
| **Monthly cost** | **$149/month** per seat (AdSpy list price) | **≈ $3.70/month** (≈ $4.60 with competitor reports) |
| **Data** | their own ad database | the live Meta Ad Library, your countries |
| **Delivery** | log in and search | e-mail, Slack, webhook, API, client report |

<details><summary>The other Ad Library scrapers and winning-ads finders in the Store — prices and what you add here</summary>

| Actor | Users / 30 d | Per ad | Extras | What you add here |
|---|---|---|---|---|
| `apify/facebook-ads-scraper` | 6,052 | $0.0058 (FREE tier) | $0.0057 e-commerce enrichment per URL | dataset mode qualifies the rows you already paid for |
| `igolaizola/facebook-ad-library-scraper` | 1,047 | $0.00075 | $0.0075 start + $0.00075 detail | no start fee, one event per ad |
| `automly/facebook-ad-library-scraper` | 242 | $0.0007 | $0.05 start; 12.9 % of runs failed in 30 days | source with 0.2 % failed runs; a failed source charges $0 |
| `azzouzana/meta-facebook-instagram-ads-library` | 173 | $0.0005 | $0.005 start + $0.0005 details | winner score, offer, AI breakdown |
| `bovi/meta-ads-library-scraper` (Meta Ad Library Spy) | — | $0.004 + $0.00005 start | every ad scraped; `is_scaled` at 3+ variants | per *qualified* creative, 0–100 score with reasons, AI breakdown |
| `davidbenittah/long-running-facebook-ads-finder` | — | $0.01 + $0.005 start | every ad running 60+ days | configurable `minDaysRunning`, dedupe, rewrite for your product |

</details>

### 💵 Pricing — what a run really costs

Pay per result: **one event per qualified ad**, plus three opt-in add-ons.

| Event | When it is charged | Price |
|---|---|---|
| `free-tier` | your first 25 qualified ads on this Actor, in any mode | **$0.00** |
| `qualified-ad-basic` | AI off — fields, offer, flags, winner score, rule hook | **$0.003** |
| `qualified-ad-ai` | AI on — plus the creative breakdown, fit score and rewrite for your product | **$0.012** |
| `ad-alert` | `changeAlerts` on — an ad you already have stopped or passed 30 / 60 / 90 days | **$0.003** |
| `landing-enriched` | `enrichLandingPages` on — a paid ad's landing page yielded a store or a product | **$0.004** |
| `advertiser-report` | `advertiserReports` on — one competitor summary row per top advertiser (≤ 10) | **$0.02** |

**Never charged:** the search, variants, filtered, political or already-received ads, unreachable pages, the
`REPORT` page, compute.

<details><summary>Which ads are free, which paid — the order behind <code>OUTPUT.chargeSplit</code></summary>

Every run's status line and `OUTPUT.chargeSplit` say the numbers (`free`, `basic`, `ai`, `freeKeptForAi`):

| Order | Rows | Charged |
|---|---|---|
| 1. free units | your first 25 qualified ads ever | $0 |
| 2. AI reserve | only when AI is on but unavailable: the last 5 free units wait for the AI | kept, $0 |
| 3. basic | rule-scored ads after that | $0.003 |
| 4. AI | AI-assessed ads after the free units | $0.012 |

*Example:* 18 free units used, AI refused, 3 new ads → status "2 free, 1 at the basic price; 5 free ads kept for when
the AI runs."

</details>

**How that compares** — $0.003 is 3× a raw Ad Library row (the median of the 5 raw scrapers a Store search shows next
to this one is $0.001; the research median $0.00075), but one qualified ad replaces 3–7 raw rows ≈ $0.0004–0.001 per
raw-row equivalent. The winning-ads finders next to it charge $0.004–$0.01 per ad, so $0.003 is **25–70 % less per
ad**.

**Worked example** — 1,000 ads scanned → 150 qualified with AI on: source $0.75 on your account + 125 × $0.012
(first 25 free) + ≈ $0.45 tokens → **$2.70 total, about $0.018 per qualified ad**. AI off: $1.13.

**AI tier, all in:** ≈ $0.015 per ad ($0.012 here + ≈ $0.003 tokens with the default model, estimated).

### 🚀 How to use it

1. **Click `Try it`** — the pre-filled example works as is (8 sample ads, nothing charged).
2. **Switch `sourceMode`** to the live search and type your `searchTerms` or `competitorPages`.
3. **Say what you sell** (`productBrief`, optional), set `minScore`, press **Start**.
4. **Open the dataset** — winning ads best-first in the Shortlist view.

📚 **Learn more:** [Step-by-step tutorial — how to find winning Facebook ads with this Actor](https://api.apify.com/v2/key-value-stores/ibHh9UNYTUhWDIrWl/records/tutorial.html)

### 🤖 What the AI tier adds

The same demo ad, AI **off** — rule winner score, offer and hook from the ad itself:

```json
{"advertiserName": "Aligna Posture", "winnerScore": 85, "score": 85, "label": "hot", "fitScore": null,
 "creative": {"hook": "Tired of that 3pm neck ache at your desk?", "angle": "social-proof",
              "offerSummary": "30% OFF · free shipping · 30-day money-back", "cta": "Shop now", "targetAudience": null,
              "emotionalTrigger": null, "formatNotes": "video ad · 12 variant(s) · facebook, instagram, messenger",
              "evidence": ["Tired of that 3pm neck ache at your desk?"]},
 "aiStatus": "off"}
```

AI **on** (`qualified-ad-ai`, $0.012) — the same keys, judged against the demo brief *"An ergonomic laptop stand for
people who work from home …"*:

```json
{"advertiserName": "Aligna Posture", "winnerScore": 85, "fitScore": 70, "score": 79, "label": "hot",
 "fitReason": "Both ads target desk‑workers with posture discomfort; the problem‑solution angle and price‑sensitive audience align with the laptop‑stand brief.",
 "creative": {"hook": "Sit taller in 7 days", "angle": "problem-solution", "offerSummary": "30% OFF + free shipping",
              "cta": "Shop now", "targetAudience": "Appears aimed at desk‑bound professionals who experience neck or posture discomfort during the workday.",
              "emotionalTrigger": "relief", "formatNotes": "The video demonstrates the device gently pulling shoulders back, visually showing the posture correction in action.",
              "evidence": ["Sit taller in 7 days", "Tired of that 3pm neck ache at your desk?", "50,000+ happy customers."]},
 "aiStatus": "ok"}
```

Cut from a local run of `storage-example/INPUT.ai.json` on 2026-09-26 (`groq:openai/gpt-oss-120b`, not yet the
platform's default model). With a strong fit it also writes `adaptationIdea`, a rewrite for your product. About 5
minutes of a strategist's work per ad, for ≈ $0.015.

#### 🧠 Ad creative analysis: hook, angle, offer

`enableAi` fills `creative` (hook, one of 10 angles, offer, CTA, audience, emotion, ≤ 3 verbatim quotes); with
`productBrief` also `fitScore` and `adaptationIdea`. `score` = winner 60 % + fit 40 %.

### ⚙️ Input

| Field | Default | What it does |
|---|---|---|
| `sourceMode` | `actor` | Live search, an existing `dataset`, or pasted records (`list`) — with nothing to search (`{}` over the API) the free demo runs, nothing charged |
| `searchTerms` | — | One Ad Library keyword search per term |
| `competitorPages` | — | Facebook pages whose ads are scanned |
| `productBrief` | — | Your product — the AI fit score and rewrite |
| `country` | `US` | Ad Library country from a list, or `ALL`; over the API `UK`, `USA` or a name work too |
| `minScore` | `40` | The field that decides what you pay: below this = not delivered, not charged |
| `maxAdsToScan` | `150` | Ads the source scans — its bill on your account (≈ $0.00075 each) |
| `maxDiscoveryChargeUsd` | `0.5` | Stops the source Actor at this spend — in the form and over the API |
| `maxQualified` | `100` | The cap on what this Actor charges: 100 × $0.012 = $1.20 at most with AI |
| `enableAi` | `true` | AI creative breakdown on/off |
| `changeAlerts` | `false` | Stopped / 30-60-90-day alerts on ads you already have |
| `advertiserReports` | `false` | One competitor summary row per top advertiser |
| `enrichLandingPages` | `false` | Store, product and price from each landing page |

All 47 options are in the **Input** tab — among them `slackWebhookUrl`, `webhookHeaders`, `period` and `dedupeStoreName`.

<details><summary>Flags for <code>targetFlags</code></summary>

`long_running` (30+ days) · `active_now` · `many_variants` (5+) · `multi_platform` (2+ placements) · `has_discount` ·
`free_shipping` · `has_price` · `bundle_offer` · `free_trial` · `urgency` · `video_creative` · `carousel_creative` ·
`ai_generated_media` (Meta's label) · `no_landing_page`. `freeShipping` works too; an unknown name stops the run with
the list of valid ones.

</details>

### 📤 Output

One dataset item per qualified ad (`rowType: ad`), change alert (`alert`) or competitor summary (`advertiser`) — JSON,
CSV or Excel. Aligna Posture from the free demo (sample record, AI off): `winnerScore` 85, 98 days running, 12 variants.

<details><summary>The full row as JSON</summary>

```json
{
  "itemId": "e02274654927",
  "rowType": "ad",
  "adArchiveId": "1184500000000001",
  "url": "https://www.facebook.com/ads/library/?id=1184500000000001",
  "collationId": "7300000000000011",
  "variantCount": 12,
  "advertiserName": "Aligna Posture",
  "advertiserLikes": 48210,
  "isActive": true,
  "startDate": "2026-06-20",
  "daysRunning": 98,
  "platforms": ["facebook", "instagram", "messenger"],
  "format": "video",
  "headline": "Sit taller in 7 days",
  "adText": "Tired of that 3pm neck ache at your desk? Aligna gently pulls your shoulders back so you sit tall without thinking about it. 50,000+ happy customers. Get 30% OFF today + free shipping.",
  "ctaText": "Shop now",
  "landingUrl": "https://aligna.example/posture-corrector",
  "landingDomain": "aligna.example",
  "landingPage": {"status": "ok", "storePlatform": "shopify", "pageType": "product", "productTitle": "Aligna Posture Corrector",
                  "price": 39.95, "currency": "USD", "rating": 4.6, "reviewsCount": 2184, "sample": true},
  "offer": {"discountPercent": 30, "freeShipping": true, "freeTrial": true,
            "phrases": ["30% OFF", "free shipping", "30-day money-back"], "summary": "30% OFF · free shipping · 30-day money-back"},
  "winnerScore": 85,
  "winnerTier": "winner",
  "scoreReasons": ["running 98 days (+40)", "still active (+15)", "12 variants of the creative (+20)", "on 3 placements (+10)"],
  "score": 85,
  "label": "hot",
  "creative": {"hook": "Tired of that 3pm neck ache at your desk?", "angle": "social-proof",
               "offerSummary": "30% OFF · free shipping · 30-day money-back", "cta": "Shop now", "targetAudience": null,
               "emotionalTrigger": null, "formatNotes": "video ad · 12 variant(s) · facebook, instagram, messenger",
               "evidence": ["Tired of that 3pm neck ache at your desk?"]},
  "generatedText": "Swipe it — Aligna Posture has run this video for 98 days (12 variant(s)); hook: “Tired of that 3pm neck ache at your desk?”; offer: 30% OFF · free shipping · 30-day money-back; CTA: Shop now.",
  "alert": null,
  "advertiserReport": null,
  "aiStatus": "off",
  "isNewSinceLastRun": true,
  "chargedEvent": "demo",
  "billedAs": "qualified-ad-basic",
  "dedupeKey": "col:7300000000000011"
}
```

</details>

#### Output fields

<details><summary>Every field of a row</summary>

| Field | Description |
|---|---|
| `itemId`, `rowType`, `adArchiveId`, `collationId`, `variantCount` | Identity of the creative and its variants; `rowType` = `ad` or `alert` |
| `url` · `adLibraryUrl` | `url` is canonical (the Ad Library link); `adLibraryUrl` = same value, kept for Ad Library pipelines |
| `advertiserName`, `advertiserPageId`, `advertiserUrl`, `advertiserLikes`, `advertiserCategories` | The advertiser's public page |
| `isActive`, `startDate`, `endDate`, `daysRunning`, `platforms`, `format` | How long and where the ad runs |
| `headline`, `adText`, `linkDescription`, `ctaText`, `ctaType` | The copy (dynamic-creative placeholders stripped) |
| `landingUrl`, `landingDomain`, `displayDomain`, `landingPage` | Landing page without tracking; `landingPage` = store, product, price, rating (`enrichLandingPages`) |
| `imageUrls`, `videoUrl`, `thumbnailUrl`, `aiGeneratedMedia` | The creative's media |
| `impressionsText`, `spend`, `reachEstimate` | Meta's own numbers — only for political / EU ads |
| `offer` | Discount %, free shipping, price, currency, free trial, bundle, urgency, verbatim phrases, summary |
| `winnerScore`, `winnerTier`, `scoreReasons`, `flags`, `targetFlagsMatched` | Rule score and findings |
| `score` · `finalScore`, `fitScore`, `fitReason`, `label` | `score` is canonical (the sort key); `finalScore` = same value, kept for Ad Library pipelines |
| `creative`, `adaptationIdea`, `generatedText` | Breakdown, rewrite for your product, the swipe-file line |
| `alert` | On `rowType: alert`: `type` (`ad-stopped` / `ad-milestone`), `milestoneDays`, `daysRunning`, `message`, `sample` |
| `advertiserReport` | On `rowType: advertiser`: active / new / stopped / 30+-day ads, avg days, share of voice, top angles and offers, best ad |
| `aiStatus`, `aiModel`, `searchTerm`, `country`, `isNewSinceLastRun` | AI `ok` / `fallback` / `off`; which search found it; new since the last run |
| `chargedEvent` · `billedAs`, `dedupeKey`, `source`, `scrapedAt` | `chargedEvent` is canonical (what the row cost); `billedAs` = its price tier, also on free rows |

</details>

**Upsert key for a CRM or Sheet:** `dedupeKey` — `col:<collationId>`, else `txt:<pageId>:<text hash>`, else
`ad:<adArchiveId>`; alert rows add `#ad-stopped` / `#ad-milestone-60`, advertiser rows are `advertiser:<pageId>`.
Map `url` and `score` — their twins carry the same value. Views: Shortlist, Creative brief (swipe file), Products &
offers, Change alerts, Competitor report, Overview. `OUTPUT` holds the funnel, `chargeSplit`, `aiCoverage`,
`competitorsToWatch`, `saveAsMonitor`, `reportUrl` and `timing`; **`DIGEST`** (Markdown) and **`REPORT`** (HTML) sit next to it.

![Products & offers view — landing domain, advertiser, days running, variants, placements and flags](https://api.apify.com/v2/key-value-stores/ibHh9UNYTUhWDIrWl/records/products.svg)

⭐ **Found it useful? A review on the Store helps others find it** — it takes a minute on the Actor's page.

### 🔁 Run it weekly

1. **Actions → Schedule** weekly with your address in `notifyEmail` — every run with news e-mails you the digest (top 10
   with links and hooks, the change alerts, competitors to watch); `slackWebhookUrl` posts it to a Slack channel.
2. Leave `onlyNewAds: true` — the next run delivers and charges **only what is new**; the memory is kept per search.
3. Turn on `changeAlerts` and `advertiserReports` — stopped ads, 30 / 60 / 90-day winners and a row per competitor.
4. Point the [swipe-file Sheet](#-swipe-file-in-google-sheets) or a webhook at the run.

Weekly cost: 10 competitor pages × 50 ads = 500 scanned ≈ $0.38 on the source + ≈ 30 new winners × $0.015 all-in +
≈ 10 alerts × $0.003 → **≈ $0.86 a week** per client monitor (+ $0.20 with competitor reports).

#### 🔁 Weekly competitor ad research

Searched by keyword? Paste `OUTPUT.saveAsMonitor` into a saved Task — pages, alerts and reports are set.
Monday's digest lists the new long-running ads and the stopped ones; forward `REPORT` to the client.

#### 🎯 Try it for your niche

| Niche | Task (`storage-example/tasks/`) |
|---|---|
| DTC / Shopify brand — 3 product terms, Shopify landing pages, 14+ days | `dtc-shopify-winners.json` |
| Agency monitor — 5 competitor pages, `notifyEmail`, alerts, reports | `agency-competitor-monitor.json` |
| Product research — 4 dropshipping terms, video only, 5+ variants | `dropshipping-products.json` |

### 🔌 Integrations, automation and API

- **E-mail / Slack** — `notifyEmail` e-mails the digest, `slackWebhookUrl` posts it to a channel as a readable message.
- **Webhook** — `webhookUrl` POSTs `{"event": "ad.qualified", "ad": {…}, "runId": "…"}` per row (`webhookBatchSize` > 1:
  `{"event": "ads.qualified", "ads": [{…}]}`); a 429 / 5xx is retried once, a failure never fails the run.
- **Google Sheets / HubSpot** — one click from the **Integrations** tab.
- **AI agents / MCP** — plain typed inputs. **First call = the free trial:** `{"sourceMode": "list", "itemsList": [...]}` or an empty `{}` (the free demo).

#### 📋 Swipe file in Google Sheets

Save your search as a Task, then in a Sheet cell A1:
`=IMPORTDATA("https://api.apify.com/v2/actor-tasks/<TASK_ID>/runs/last/dataset/items?format=csv&view=creativeBrief&token=<SCOPED_TOKEN>")`
— hook, angle, offer, your rewrite and `thumbnailUrl` (`=IMAGE(L2)`), refreshed after every scheduled run. **Make /
n8n:** *Watch task runs → Get dataset items → Sheets / Notion / Airtable: add row*.

<details><summary>API snippets — Python, JavaScript and MCP</summary>

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("rich_minds/fb-ad-library-winning-ads").call(run_input={
    "sourceMode": "list",
    "itemsList": [{"ad_archive_id": "1184500000000001", "page_name": "Aligna Posture", "is_active": True,
                   "start_date": 1781942400, "snapshot": {"body": {"text": "Tired of that 3pm neck ache at your desk?"}}}],
    "productBrief": "An ergonomic laptop stand for people who work from home.",
    "maxQualified": 50,
    "maxDiscoveryChargeUsd": 0.5,  # spend cap on your account once you switch to "sourceMode": "actor"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["advertiserName"], item["score"], item["label"])
```

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('rich_minds/fb-ad-library-winning-ads').call({
    sourceMode: 'list',
    itemsList: [{ ad_archive_id: '1184500000000001', page_name: 'Aligna Posture', is_active: true,
                  start_date: 1781942400, snapshot: { body: { text: 'Tired of that 3pm neck ache at your desk?' } } }],
    productBrief: 'An ergonomic laptop stand for people who work from home.',
    maxQualified: 50,
    maxDiscoveryChargeUsd: 0.5, // spend cap on your account once you switch to sourceMode: 'actor'
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => [i.advertiserName, i.score, i.label]));
```

```json
{"mcpServers": {"apify": {"url": "https://mcp.apify.com/?actors=rich_minds/fb-ad-library-winning-ads"}}}
```

Then ask: *"Run fb-ad-library-winning-ads in `list` mode on these records first (free), show me the hot ads, then
search `searchTerms: ["posture corrector"]` in `country: US` with `sourceMode: actor` and `maxDiscoveryChargeUsd: 0.5`."*

</details>

#### Run outcomes — what your integration sees

<details><summary>Every outcome: run status, dataset, <code>OUTPUT</code> field, charged?, what to do</summary>

| Outcome | Run status | Dataset | `OUTPUT` | Charged? | What to do |
|---|---|---|---|---|---|
| Free demo (the pre-filled sample) | SUCCEEDED | sample ads | `qualified`, `demoIgnoredFields` | no | switch the source; typed terms next to the demo are said to be unsearched |
| Success | SUCCEEDED | qualified ads, best first, then alerts | funnel, `chargedEvents`, `chargeSplit` | per row | — |
| Only change alerts | SUCCEEDED | alert rows | `changeAlerts` | per alert | — |
| Nothing new, reports on | SUCCEEDED | advertiser rows | `advertiserReports`, `competitorsToWatch` | per advertiser row | — |
| Search returned 0 ads | SUCCEEDED | empty | `qualified: 0` | no | broader `searchTerms`, `country` ALL, `activeStatus` all |
| Nothing matched | SUCCEEDED | empty | `qualified: 0`, `stats` | no | loosen `minScore` / filters |
| Demo text still in place | SUCCEEDED | empty | `inputNeeded` | no | replace the field the status names |
| Invalid input | FAILED | empty | — | no | fix the field the status message names |
| Source failed | FAILED | empty | `sourceError` | no | a plan that cannot run Store Actors: use `dataset` mode; else follow the reason |
| AI unavailable | SUCCEEDED | rule-scored ads (`aiStatus: fallback`) | `aiError`, `chargeSplit` | the split the status names | `llmProvider: byok` with your own key |

</details>

### 👥 Who is it for?

| You are… | You run it to… | Start with |
|---|---|---|
| DTC / Shopify / dropshipping owner | the competitor ads that run for weeks, with hook and offer | product terms + `productBrief` |
| Agency media buyer / creative strategist | Monday's new long-running and stopped competitor ads, a client report | `competitorPages` + `advertiserReports` |
| Product researcher | the products and prices long-running ads push | `searchTerms` + `enrichLandingPages` |
| AI agent / automation | "top 20 winning ads for a keyword as JSON" | `searchTerms`, `maxQualified: 20` |

#### 🛒 Dropshipping winning products: landing domains and offers

The `Products & offers` view: domain, store, product, price, discount, days running.

### 🧠 How the AI works

<details><summary>Grounding, fit score, model and fallback</summary>

- **Grounded, not generative.** The model sees one ad (headline, text ≤ 1,500 chars, link description, CTA, format,
  the offer phrases the rules found, advertiser) and returns a typed breakdown. Evidence not copied verbatim from the ad
  is dropped; performance or spend claims are removed; the audience is always "Appears aimed at …".
- **Your product, not a generic score.** The fit score measures how well the ad's angle transfers to your
  `productBrief`; its reason must name a word of the ad or the brief. No brief, no fit score and no rewrite.
- **Never the competitor's words.** A rewrite that mentions their brand, domain or any number from their ad is dropped.
- **Only where it matters.** The best rule-scored ads get the AI pass (`aiCandidateMultiplier` × `maxQualified`).
- **No keys required.** Default `anthropic/claude-haiku-4.5` through Apify's model access; `llmProvider: "byok"` for
  your own OpenAI, Anthropic, Gemini or Groq key, or any OpenRouter slug in `llmModel`.
- **Graceful fallback.** If the model cannot be reached, the ad keeps its rule hook, offer and CTA, a keyword-overlap
  fit score and `aiStatus: fallback`, at the basic price (the status names the free / basic split).

</details>

### 🔒 Data, compliance and limits

- Public data only: the Meta Ad Library's advertiser pages and ads, no user data, no login; landing pages read once.
- Impressions and spend exist only for political / EU ads; days running is a proxy for profit, not a performance figure.
- Keep your use within Meta's terms and the law (GDPR, CCPA); never copy a creative — the rewrite exists for that.

### ❓ FAQ

**How much will my first real search cost?** 3 terms × 50 ads = 150 scanned ≈ $0.11 on your account, capped by
`maxDiscoveryChargeUsd` ($0.50); that yields ≈ 20–50 qualified ads — the first 25 free, the rest at $0.003 ($0.015
with AI, all in).

**Which Apify plan do I need?** Any plan runs the free demo and `dataset` / `list` mode. The live search and Apify's
model access need a plan that can run Store Actors; on the Free plan qualify a dataset you already have and use
`llmProvider: "byok"` with your own key.

**Does it find Instagram ads?** Yes — Meta's Ad Library covers Instagram, and `platforms: ["instagram"]` keeps only
ads shown there: an Instagram ads library search with the same winner score and AI breakdown.

<details><summary>Is it a Facebook Ads Library scraper? How is it different from AdSpy or Minea?</summary>

**Is this a Facebook Ads Library scraper?** It runs one for you — `curious_coder/facebook-ads-library-scraper` on your
account (≈ $0.00075 per ad scanned) — and adds the collapse, filters, winner score and AI. In `dataset` mode it
qualifies rows from that scraper or `apify/facebook-ads-scraper` you already have. It is also a Meta ads scraper for
Messenger and Audience Network placements.

**Does it search the Meta Ad Library, or only Facebook?** The Meta Ad Library — one archive for Facebook, Instagram,
Messenger and Audience Network ads; `platforms` keeps the placements you want.

**How is this different from a Facebook ad spy tool like AdSpy or Minea?** They sell a monthly seat on their own
database (AdSpy lists $149/month); this reads the live Meta Ad Library and charges $0.003 per qualified ad, first 25
free, with API, MCP, schedule, e-mail and webhook.

</details>

**How long does a run take?** The demo about 1 s; the source ~2 min for 150 ads (estimate). With AI through Apify's
model access a few seconds per ad (estimate). With your own key (`llmProvider: byok`) 2 calls at a time, one after a
rate limit, waiting what the provider asks: a rate-limited key measured 27 s per ad, so the **worst case per 100
qualified ads is ≈ 45 min**; after 120 s of unbroken rate limits the rest keep their rule score. Pass `timeoutSecs:
3600` for `maxQualified` 100 with AI; `OUTPUT.timing` reports each run's phases.

**Can I use it for competitor ad research and ad creative analysis?** Yes — `competitorPages` +
`advertiserReports` for a summary per rival; `enableAi` breaks each creative into hook, angle, offer and audience.

**Can I find dropshipping winning products with it?** Yes — search product terms, set `minVariants: 5`,
`minDaysRunning: 21` and `enrichLandingPages: true`, and open the Products & offers view.

<details><summary>More questions: empty runs, double charges, AI failures, legality, scheduling</summary>

**What happens if nothing matches my filters?** The run succeeds with 0 rows and charges nothing; the status names how
many ads each filter dropped.

**Will I be charged for the same ad twice?** Not with `onlyNewAds` on (default): every delivered ad and its variants
are remembered on your account. A change alert is a separate, opt-in row.

**What if the AI fails?** The ad keeps its rule hook, offer and winner score at the basic price; the status names how
many rows were free, basic and kept for the AI. A model error never fails the run.

**Is the data public / is this legal?** Yes — the Meta Ad Library is Meta's public archive of running ads, read without
login; you stay responsible for using it within Meta's terms.

**Can I schedule it?** Yes — see [Run it weekly](#-run-it-weekly); you only pay for new ads and the alerts you turn on.

</details>

### 🧩 More Actors from the same developer

Not quite your use case? The same pay-per-qualified-result model, closest to this Actor's buyers first:

- **[Instagram Influencer Finder](https://apify.com/rich_minds/instagram-creator-qualifier)** — instagram creators to run the winning angle with: vetted for your niche, with a contact
- **[LinkedIn Buying Intent Leads](https://apify.com/rich_minds/linkedin-intent-leads)** — people posting about competitor switching: linkedin buying intent, with an opener
- **[YouTube Outlier Videos Finder](https://apify.com/rich_minds/youtube-video-research-ai)** — youtube competitor analysis: the videos that beat their channel's average, and why

### 🆘 Support

Missing something? Open an issue on the Actor's page — buyer requests ship first.

### 📝 Changelog

One line per published build, newest first — `/actor-publish` adds it with the commit subject.

- **0.3** (2026-09-26) — competitor report rows (`advertiserReports`), competitors to watch + `saveAsMonitor`, the
  client-ready `REPORT` page, Slack digest, `country` as a list, AI coverage in every AI status, one `creative` shape.

<details><summary>Earlier builds: 0.2, 0.1.1, 0.1</summary>

- **0.2** (2026-09-26) — change alerts (`changeAlerts`), landing-page store / product / price (`enrichLandingPages`),
  the free / basic / AI split in the status, unsearched demo terms named, `url` / `score` canonical.
- **0.1.1** (2026-09-25) — Actor handle in the snippets, README attached to the build.
- **0.1** (2026-09-25) — initial release: Ad Library search, variant collapse, winner score, offer extraction, AI creative breakdown.

</details>

# Actor input Schema

## `sourceMode` (type: `string`):

<b>actor</b> — search the Meta Ad Library live with <code>curious\_coder/facebook-ads-library-scraper</code> on your account (≈ $0.00075 per ad scanned, billed by that Actor; needs an Apify plan that can run Store Actors — if yours cannot, the run stops at once and nothing is charged). <b>dataset</b> — qualify an existing dataset from that scraper or from <code>apify/facebook-ads-scraper</code>. <b>list</b> — Ad Library records you paste in. The form starts on the free demo (8 sample ads, nothing charged); an API call that names nothing to search (<code>{}</code>) runs the same demo.

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

Keywords searched in the Meta Ad Library, one search per term — a product (<i>posture corrector</i>), a niche (<i>dog harness</i>) or a claim (<i>vitamin c serum</i>). Each term runs as an Ad Library keyword search in your <b>country</b>. The prefilled terms are the demo's — replace them with yours.

## `productBrief` (type: `string`):

Describe what <b>you</b> sell in one or two sentences. The AI scores how well each competitor ad's angle would transfer to your product (fit score) and rewrites its angle for your product — never copying their brand, claims or prices. Leave empty for the creative breakdown only.

## `minScore` (type: `integer`):

The field that decides what you pay: ads whose final score (winner score, blended 60/40 with the AI fit score when you gave a product brief) is below this are discarded and <b>not charged</b>. 70+ = winners only.

## `maxDiscoveryChargeUsd` (type: `number`):

Hard cap on what the source Actor run may charge your account in <b>actor</b> mode — $0.50 in the form and for an API or agent call that leaves it out, so a first real search can never cost more. Raise it for bigger searches.

## `maxQualified` (type: `integer`):

The cap on what <b>this Actor</b> charges per run: at most this many qualified ads are delivered and billed, best first — the worst case is 100 × $0.012 = <b>$1.20</b> with AI on ($0.30 with AI off), plus the source's own cap above (Max source spend). Your first 25 ads are free.

## `enableAi` (type: `boolean`):

The AI writes the hook, angle, offer, CTA, audience and emotional trigger with verbatim evidence quotes, a fit score against your product brief and a rewrite of the angle for your product. <b>On = $0.012 per qualified ad + AI tokens; off = $0.003</b> (rule-based winner score, offer and hook only).

## `maxAdsToScan` (type: `integer`):

Total ads the source scrapes across all searches — what it bills on your account (≈ $0.00075 each, so 150 ≈ $0.11). Variants, dead and filtered ads among them are never charged here.

## `competitorPages` (type: `array`):

Facebook page URLs (or page names) of the competitors to watch — every ad they run is scanned, sorted by impressions. Use it for weekly competitor monitoring next to, or instead of, search terms.

## `adLibraryUrls` (type: `array`):

Any Meta Ad Library URL you already use (a search with your own filters, a page's ad list) — passed to the source as is.

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

The Ad Library country searched — pick from the list (<b>All countries</b> searches every country). Over the API send the two-letter code (<code>US</code>, <code>GB</code>, <code>DE</code> …) or <code>ALL</code>; <code>UK</code>, <code>USA</code> and country names are mapped for you, anything else stops the run at once with the valid codes.

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

<b>Active</b> = ads still running today (the winners); <b>All</b> also includes ads that stopped; <b>Inactive</b> = only stopped ads. Used in the search and as a free filter.

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

Only image or only video creatives — in the search and as a free filter.

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

For <b>competitor pages</b>: only ads seen in this window.

## `maxAdsPerSearch` (type: `integer`):

The most ads the source takes from one search term or page, so one broad term cannot use the whole scan budget.

## `minWinnerScore` (type: `integer`):

The free rule bar applied before any AI token is spent: days running (up to 40 points), still active (15), variants (20), 2+ placements (10), impressions when Meta publishes them (15). 70+ = winner, 40–69 = promising.

## `minDaysRunning` (type: `integer`):

Drop ads younger than this — an ad that has run for weeks is the only public sign that it pays for itself.

## `minVariants` (type: `integer`):

Only creatives the advertiser runs in at least this many variants (Meta's collation count — a scaled creative has many).

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

Keep ads shown on at least one of these placements. Empty = any.

## `landingDomainIncludes` (type: `array`):

Keep only ads whose landing page is on one of these domains (e.g. <code>myshopify.com</code>, <code>amazon.com</code>).

## `landingDomainExcludes` (type: `array`):

Drop ads that link to these domains (marketplaces, your own site).

## `excludeAdvertisers` (type: `array`):

Your own brand, your clients or anyone you do not want in the list — a page name (part of it), page id or landing domain.

## `includePoliticalAds` (type: `boolean`):

Off by default: political and social-issue ads are dropped before any charge.

## `adLanguage` (type: `string`):

Keep only ads whose copy is in this language (a stop-word guess; ads it cannot tell are kept).

## `targetFlags` (type: `array`):

Only deliver ads that have at least one of these flags, e.g. <code>free\_shipping</code>, <code>has\_discount</code>, <code>long\_running</code>, <code>video\_creative</code> (<code>freeShipping</code> works too). Leave empty to keep everything; an unknown name stops the run at once with the list of valid ones.

## `suppressionList` (type: `array`):

Ad archive ids, Ad Library URLs or dedupe keys to never output. Skipped before any processing and never charged.

## `llmProvider` (type: `string`):

<b>Apify (no keys)</b> — the AI runs through Apify's built-in OpenRouter proxy; tokens are billed to your Apify account at OpenRouter's rates. <b>My own key</b> — use your OpenAI / Anthropic / Gemini / Groq key instead; a free-tier key is slower (2 calls at a time, one after a rate limit — measured up to 27 s per ad, so the worst case per 100 qualified ads is ≈ 45 min: 200 ads in the AI pool, 2 at a time). The AI stops before the run's timeout and the rest keep their rule score.

## `llmModel` (type: `string`):

Leave empty for the default (<code>anthropic/claude-haiku-4.5</code>). Apify mode takes an OpenRouter slug such as <code>openai/gpt-4.1-mini</code>; own-key mode takes <code>provider:model</code>, e.g. <code>anthropic:claude-haiku-4-5-20251001</code>.

## `llmApiKey` (type: `string`):

Required when <b>AI model access</b> is <i>My own API key</i>. Stored encrypted by Apify, never logged.

## `outputLanguage` (type: `string`):

Language of the creative breakdown and of the rewrite for your product (quotes stay in the ad's language).

## `aiCandidateMultiplier` (type: `integer`):

How many of the best rule-scored ads get the AI pass, as a multiple of <b>Max qualified</b>. Higher = more thorough, slower, more tokens.

## `notifyEmail` (type: `string`):

After every run with at least one new ad, the run's digest (how many are new, the top 10 with links and hooks) is e-mailed here through Apify's send-mail Actor. Schedule the run weekly and the new winning ads come to your inbox — no Slack or Zapier needed. Never sent for the free demo.

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

A Slack incoming-webhook URL (<code>https://hooks.slack.com/services/…</code>). After every run with something new, the digest — new ads with hook and days running, change alerts, competitors to watch and the report link — is posted to that channel as a readable message, not raw JSON. Never posted for the free demo; a refused post is one log line, the run still succeeds.

## `changeAlerts` (type: `boolean`):

For a scheduled monitor: every run also re-checks the ads you received before and adds one <code>rowType: alert</code> row when a competitor <b>stopped</b> an ad (a loser killed) or an ad passed <b>30 / 60 / 90 days</b> (a winner confirmed) — in the dataset, the e-mail digest and the webhook. <b>$0.003 per alert</b> (<code>ad-alert</code>), never on the free demo. To see an ad stop, the search also fetches stopped ads (inside <b>Max ads to scan</b>); new rows stay active-only.

## `advertiserReports` (type: `boolean`):

Adds one <code>rowType: advertiser</code> row per top advertiser of the run (up to 10): active ads, new this run, stopped, ads running 30+ days, average days running, share of voice, top angles and offers, best ad — the per-competitor summary an agency forwards. <b>$0.02 per advertiser row</b> (<code>advertiser-report</code>), never on the free demo (which shows one sample row). A weekly monitor with nothing new still gets its reports.

## `enrichLandingPages` (type: `boolean`):

Opens the landing page of every qualified ad and adds <code>landingPage</code>: store platform (Shopify, WooCommerce …), product title, price, rating and reviews count — what the page states itself, nothing guessed. <b>$0.004 per page that yields a store or a product</b> (<code>landing-enriched</code>); unreachable pages and your free ads cost nothing. Adds a few seconds per 5 pages; stops before the run's timeout.

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

Qualified ads are POSTed here as JSON (Zapier, Make, n8n, your CRM). For a Slack channel use <b>Post the digest to Slack</b> above — a Slack webhook here would receive raw JSON.

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

Extra HTTP headers for the webhook, e.g. <code>{"Authorization": "Bearer …"}</code>.

## `webhookBatchSize` (type: `integer`):

1 = one POST per ad the moment it is ready. Higher = one POST per N ads.

## `onlyNewAds` (type: `boolean`):

Remembers every ad (and each of its variants) you received, in a named key-value store on your account, and skips it in later runs — a weekly schedule delivers and charges only new ads. Off: earlier ads come again, marked <code>isNewSinceLastRun: false</code>.

## `dedupeStoreName` (type: `string`):

Key-value store used for the cross-run memory. Left at the default, the memory is kept per search (terms, pages, URLs, country and product brief): each client's monitor keeps its own list. Type your own name to share one memory across searches.

## `datasetId` (type: `string`):

Only for <b>dataset</b> mode: a dataset of <code>curious\_coder/facebook-ads-library-scraper</code> or <code>apify/facebook-ads-scraper</code>. Pick it so the Actor is granted read access to it.

## `itemsList` (type: `array`):

Only for <b>list</b> mode. JSON array of Meta Ad Library records in either scraper's shape (<code>ad\_archive\_id</code> + <code>snapshot</code>, or <code>adArchiveID</code> + <code>snapshot</code>). Records without an archive id are skipped and never charged.

## `discoveryActorId` (type: `string`):

Actor used in <b>actor</b> mode. Any Actor whose output has the Meta Ad Library fields listed in the README works.

## `discoveryInput` (type: `object`):

Only for <b>actor</b> mode. Keys merged over the input this Actor builds for the source (e.g. <code>{"scrapeAdDetails": true}</code>). See the source Actor's input schema.

## `maxToProcess` (type: `integer`):

Upper bound on how many ads are scored in one run (controls run time). Default = 3 × max qualified.

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

Not used by this Actor itself (the source Actor brings its own proxy); kept for compatibility.

## Actor input object example

```json
{
  "sourceMode": "list",
  "searchTerms": [
    "posture corrector",
    "dog harness",
    "vitamin c serum"
  ],
  "productBrief": "An ergonomic laptop stand for people who work from home — adjustable height, folds flat, aluminium, $49.",
  "minScore": 40,
  "maxDiscoveryChargeUsd": 0.5,
  "maxQualified": 100,
  "enableAi": true,
  "maxAdsToScan": 150,
  "country": "US",
  "activeStatus": "active",
  "mediaType": "all",
  "period": "all",
  "maxAdsPerSearch": 50,
  "minWinnerScore": 40,
  "minDaysRunning": 7,
  "minVariants": 1,
  "includePoliticalAds": false,
  "adLanguage": "any",
  "llmProvider": "apify",
  "outputLanguage": "English",
  "aiCandidateMultiplier": 2,
  "changeAlerts": false,
  "advertiserReports": false,
  "enrichLandingPages": false,
  "webhookBatchSize": 1,
  "onlyNewAds": true,
  "dedupeStoreName": "fb-ad-library-winning-ads-seen",
  "itemsList": [
    {
      "ad_archive_id": "1184500000000001",
      "collation_id": "7300000000000011",
      "collation_count": 12,
      "page_id": "100000000000101",
      "page_name": "Aligna Posture",
      "is_active": true,
      "start_date": 1781942400,
      "end_date": null,
      "publisher_platform": [
        "FACEBOOK",
        "INSTAGRAM",
        "MESSENGER"
      ],
      "categories": [
        "UNKNOWN"
      ],
      "contains_digital_created_media": false,
      "impressions_with_index": {
        "impressions_text": null
      },
      "snapshot": {
        "page_name": "Aligna Posture",
        "page_profile_uri": "https://www.facebook.com/alignaposture.example",
        "page_like_count": 48210,
        "page_categories": [
          "Health & wellness website"
        ],
        "display_format": "VIDEO",
        "title": "Sit taller in 7 days",
        "body": {
          "text": "Tired of that 3pm neck ache at your desk? Aligna gently pulls your shoulders back so you sit tall without thinking about it. 50,000+ happy customers. Get 30% OFF today + free shipping."
        },
        "link_description": "30-day money-back guarantee",
        "cta_text": "Shop now",
        "cta_type": "SHOP_NOW",
        "link_url": "https://aligna.example/posture-corrector?utm_source=facebook&utm_campaign=q3&fbclid=IwAR0x",
        "caption": "ALIGNA.EXAMPLE",
        "images": [],
        "videos": [
          {
            "video_hd_url": "https://video.example/aligna-hook-hd.mp4",
            "video_preview_image_url": "https://img.example/aligna-preview.jpg"
          }
        ],
        "cards": []
      },
      "searchTerm": "posture corrector",
      "landingPage": {
        "status": "ok",
        "storePlatform": "shopify",
        "pageType": "product",
        "productTitle": "Aligna Posture Corrector",
        "price": 39.95,
        "currency": "USD",
        "rating": 4.6,
        "reviewsCount": 2184,
        "pageTitle": "Aligna Posture Corrector – Aligna",
        "fetchedUrl": "https://aligna.example/posture-corrector",
        "sample": true
      }
    },
    {
      "ad_archive_id": "1184500000000002",
      "collation_id": "7300000000000011",
      "collation_count": 12,
      "page_id": "100000000000101",
      "page_name": "Aligna Posture",
      "is_active": true,
      "start_date": 1784361600,
      "publisher_platform": [
        "FACEBOOK",
        "INSTAGRAM"
      ],
      "snapshot": {
        "display_format": "VIDEO",
        "title": "Sit taller in 7 days",
        "body": {
          "text": "Neck ache at your desk? Aligna pulls your shoulders back. Get 30% OFF today."
        },
        "cta_text": "Shop now",
        "link_url": "https://aligna.example/posture-corrector?utm_source=facebook&utm_content=v2",
        "caption": "aligna.example",
        "videos": [
          {
            "video_sd_url": "https://video.example/aligna-v2-sd.mp4"
          }
        ]
      },
      "searchTerm": "posture corrector"
    },
    {
      "adArchiveID": "1184500000000003",
      "collationId": "7300000000000022",
      "collationCount": 6,
      "pageID": "100000000000202",
      "pageName": "Pawtrail",
      "isActive": true,
      "startDateFormatted": "2026-08-01T09:00:00.000Z",
      "publisherPlatform": [
        "facebook",
        "instagram"
      ],
      "containsDigitalCreatedMedia": false,
      "snapshot": {
        "pageProfileUri": "https://www.facebook.com/pawtrail.example",
        "pageLikeCount": 12940,
        "pageCategories": [
          "Pet supplies"
        ],
        "displayFormat": "CAROUSEL",
        "body": {
          "text": "My dog pulled like a train until we tried the Pawtrail no-pull harness. Now walks are actually fun. Buy 1, get 1 50% off — this week only."
        },
        "ctaText": "Shop now",
        "ctaType": "SHOP_NOW",
        "caption": "pawtrail.example",
        "cards": [
          {
            "title": "The harness that stops the pull",
            "body": "My dog pulled like a train until we tried the Pawtrail no-pull harness.",
            "linkUrl": "https://pawtrail.example/no-pull-harness?utm_source=meta",
            "originalImageUrl": "https://img.example/pawtrail-card-1.jpg"
          },
          {
            "title": "Fits in 30 seconds",
            "body": "Two clips, no fuss.",
            "linkUrl": "https://pawtrail.example/no-pull-harness",
            "originalImageUrl": "https://img.example/pawtrail-card-2.jpg"
          }
        ]
      },
      "searchTerm": "dog harness"
    },
    {
      "ad_archive_id": "1184500000000004",
      "collation_id": "7300000000000033",
      "collation_count": 4,
      "page_id": "100000000000303",
      "page_name": "Lumière Skin Lab",
      "is_active": true,
      "start_date": 1784102400,
      "publisher_platform": [
        "FACEBOOK",
        "INSTAGRAM",
        "AUDIENCE_NETWORK"
      ],
      "impressions_with_index": {
        "impressions_text": "100K-200K",
        "impressions_index": 4
      },
      "snapshot": {
        "page_like_count": 30511,
        "page_categories": [
          "Beauty, cosmetic & personal care"
        ],
        "display_format": "IMAGE",
        "title": "Brighter skin in 14 days",
        "body": "Dermatologist-formulated 15% vitamin C serum for dull, tired skin. Brighter in 14 days or your money back. Now $29.99 (was $45).",
        "link_description": "Free shipping on orders over $35",
        "cta_text": "Learn more",
        "cta_type": "LEARN_MORE",
        "link_url": "https://lumiere-skinlab.example/vitamin-c?utm_source=fb&utm_medium=paid",
        "caption": "lumiere-skinlab.example",
        "images": [
          {
            "original_image_url": "https://img.example/lumiere-serum.jpg",
            "resized_image_url": "https://img.example/lumiere-serum-600.jpg"
          }
        ]
      },
      "searchTerm": "vitamin c serum",
      "reach_estimate": "80K-120K",
      "landingPage": {
        "status": "ok",
        "storePlatform": "woocommerce",
        "pageType": "product",
        "productTitle": "15% Vitamin C Brightening Serum",
        "price": 29.99,
        "currency": "USD",
        "rating": 4.4,
        "reviewsCount": 612,
        "pageTitle": "Vitamin C Serum | Lumière Skin Lab",
        "fetchedUrl": "https://lumiere-skinlab.example/vitamin-c",
        "sample": true
      }
    },
    {
      "ad_archive_id": "1184500000000005",
      "collation_id": "7300000000000044",
      "collation_count": 2,
      "page_id": "100000000000404",
      "page_name": "StandUp Co",
      "is_active": true,
      "start_date": 1788595200,
      "publisher_platform": [
        "FACEBOOK"
      ],
      "snapshot": {
        "page_categories": [
          "Furniture"
        ],
        "display_format": "VIDEO",
        "title": "Any desk. Standing in 10 seconds.",
        "body": {
          "text": "Your back will thank you. The StandUp converter turns any desk into a standing desk in 10 seconds. Free delivery across the US."
        },
        "cta_text": "Shop now",
        "link_url": "https://standup-co.example/converter",
        "caption": "standup-co.example",
        "videos": [
          {
            "video_hd_url": "https://video.example/standup-demo.mp4",
            "video_preview_image_url": "https://img.example/standup-preview.jpg"
          }
        ]
      },
      "searchTerm": "posture corrector"
    },
    {
      "ad_archive_id": "1184500000000006",
      "page_id": "100000000000505",
      "page_name": "Citizens for Cleaner Parks",
      "is_active": true,
      "start_date": 1780300800,
      "categories": [
        "POLITICAL"
      ],
      "political_countries": [
        "US"
      ],
      "spend": {
        "lower_bound": "1000",
        "upper_bound": "1499"
      },
      "currency": "USD",
      "publisher_platform": [
        "FACEBOOK",
        "INSTAGRAM"
      ],
      "snapshot": {
        "display_format": "IMAGE",
        "body": {
          "text": "Vote yes on Measure 12 for cleaner city parks."
        },
        "cta_text": "Learn more",
        "link_url": "https://cleanerparks.example/measure-12"
      }
    },
    {
      "ad_archive_id": "1184500000000007",
      "collation_id": "7300000000000066",
      "collation_count": 1,
      "page_id": "100000000000606",
      "page_name": "GlowBox",
      "is_active": true,
      "start_date": 1790150400,
      "publisher_platform": [
        "INSTAGRAM"
      ],
      "snapshot": {
        "display_format": "IMAGE",
        "body": {
          "text": "New drop: the GlowBox LED mask. Link in bio."
        },
        "cta_text": "Shop now",
        "link_url": "https://glowbox.example/led-mask"
      },
      "searchTerm": "vitamin c serum"
    },
    {
      "ad_archive_id": "1184500000000008",
      "collation_id": "7300000000000077",
      "collation_count": 3,
      "page_id": "100000000000707",
      "page_name": "SnoozeWell",
      "is_active": false,
      "start_date": 1772352000,
      "end_date": 1780128000,
      "publisher_platform": [
        "FACEBOOK",
        "INSTAGRAM"
      ],
      "snapshot": {
        "display_format": "IMAGE",
        "body": {
          "text": "Fall asleep in 10 minutes with the SnoozeWell weighted eye mask. Free trial for 30 nights."
        },
        "cta_text": "Try it free",
        "link_url": "https://snoozewell.example/mask"
      }
    }
  ],
  "discoveryActorId": "curious_coder/facebook-ads-library-scraper",
  "discoveryInput": {},
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `qualified` (type: `string`):

All qualified ads as JSON, best-scoring first.

## `sheet` (type: `string`):

The same ads as a spreadsheet.

## `report` (type: `string`):

The run as one page to forward: competitors to watch, the winning ads with thumbnail, hook, offer, days running and AI breakdown, and what changed since the last run.

## `digest` (type: `string`):

New ads, change alerts and competitors to watch — the text the e-mail and Slack digest send.

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

JSON record with the funnel (loaded -> filtered -> AI-assessed -> qualified), per-reason skip counts, charged events by type, free-tier ads used and remaining, whether a budget limit was reached, webhook delivery counts and the dedupe store size.

# 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 = {
    "sourceMode": "list",
    "searchTerms": [
        "posture corrector",
        "dog harness",
        "vitamin c serum"
    ],
    "productBrief": "An ergonomic laptop stand for people who work from home — adjustable height, folds flat, aluminium, $49.",
    "maxDiscoveryChargeUsd": 0.5,
    "maxQualified": 100,
    "maxAdsToScan": 150,
    "maxAdsPerSearch": 50,
    "itemsList": [
        {
            "ad_archive_id": "1184500000000001",
            "collation_id": "7300000000000011",
            "collation_count": 12,
            "page_id": "100000000000101",
            "page_name": "Aligna Posture",
            "is_active": true,
            "start_date": 1781942400,
            "end_date": null,
            "publisher_platform": [
                "FACEBOOK",
                "INSTAGRAM",
                "MESSENGER"
            ],
            "categories": [
                "UNKNOWN"
            ],
            "contains_digital_created_media": false,
            "impressions_with_index": {
                "impressions_text": null
            },
            "snapshot": {
                "page_name": "Aligna Posture",
                "page_profile_uri": "https://www.facebook.com/alignaposture.example",
                "page_like_count": 48210,
                "page_categories": [
                    "Health & wellness website"
                ],
                "display_format": "VIDEO",
                "title": "Sit taller in 7 days",
                "body": {
                    "text": "Tired of that 3pm neck ache at your desk? Aligna gently pulls your shoulders back so you sit tall without thinking about it. 50,000+ happy customers. Get 30% OFF today + free shipping."
                },
                "link_description": "30-day money-back guarantee",
                "cta_text": "Shop now",
                "cta_type": "SHOP_NOW",
                "link_url": "https://aligna.example/posture-corrector?utm_source=facebook&utm_campaign=q3&fbclid=IwAR0x",
                "caption": "ALIGNA.EXAMPLE",
                "images": [],
                "videos": [
                    {
                        "video_hd_url": "https://video.example/aligna-hook-hd.mp4",
                        "video_preview_image_url": "https://img.example/aligna-preview.jpg"
                    }
                ],
                "cards": []
            },
            "searchTerm": "posture corrector",
            "landingPage": {
                "status": "ok",
                "storePlatform": "shopify",
                "pageType": "product",
                "productTitle": "Aligna Posture Corrector",
                "price": 39.95,
                "currency": "USD",
                "rating": 4.6,
                "reviewsCount": 2184,
                "pageTitle": "Aligna Posture Corrector – Aligna",
                "fetchedUrl": "https://aligna.example/posture-corrector",
                "sample": true
            }
        },
        {
            "ad_archive_id": "1184500000000002",
            "collation_id": "7300000000000011",
            "collation_count": 12,
            "page_id": "100000000000101",
            "page_name": "Aligna Posture",
            "is_active": true,
            "start_date": 1784361600,
            "publisher_platform": [
                "FACEBOOK",
                "INSTAGRAM"
            ],
            "snapshot": {
                "display_format": "VIDEO",
                "title": "Sit taller in 7 days",
                "body": {
                    "text": "Neck ache at your desk? Aligna pulls your shoulders back. Get 30% OFF today."
                },
                "cta_text": "Shop now",
                "link_url": "https://aligna.example/posture-corrector?utm_source=facebook&utm_content=v2",
                "caption": "aligna.example",
                "videos": [
                    {
                        "video_sd_url": "https://video.example/aligna-v2-sd.mp4"
                    }
                ]
            },
            "searchTerm": "posture corrector"
        },
        {
            "adArchiveID": "1184500000000003",
            "collationId": "7300000000000022",
            "collationCount": 6,
            "pageID": "100000000000202",
            "pageName": "Pawtrail",
            "isActive": true,
            "startDateFormatted": "2026-08-01T09:00:00.000Z",
            "publisherPlatform": [
                "facebook",
                "instagram"
            ],
            "containsDigitalCreatedMedia": false,
            "snapshot": {
                "pageProfileUri": "https://www.facebook.com/pawtrail.example",
                "pageLikeCount": 12940,
                "pageCategories": [
                    "Pet supplies"
                ],
                "displayFormat": "CAROUSEL",
                "body": {
                    "text": "My dog pulled like a train until we tried the Pawtrail no-pull harness. Now walks are actually fun. Buy 1, get 1 50% off — this week only."
                },
                "ctaText": "Shop now",
                "ctaType": "SHOP_NOW",
                "caption": "pawtrail.example",
                "cards": [
                    {
                        "title": "The harness that stops the pull",
                        "body": "My dog pulled like a train until we tried the Pawtrail no-pull harness.",
                        "linkUrl": "https://pawtrail.example/no-pull-harness?utm_source=meta",
                        "originalImageUrl": "https://img.example/pawtrail-card-1.jpg"
                    },
                    {
                        "title": "Fits in 30 seconds",
                        "body": "Two clips, no fuss.",
                        "linkUrl": "https://pawtrail.example/no-pull-harness",
                        "originalImageUrl": "https://img.example/pawtrail-card-2.jpg"
                    }
                ]
            },
            "searchTerm": "dog harness"
        },
        {
            "ad_archive_id": "1184500000000004",
            "collation_id": "7300000000000033",
            "collation_count": 4,
            "page_id": "100000000000303",
            "page_name": "Lumière Skin Lab",
            "is_active": true,
            "start_date": 1784102400,
            "publisher_platform": [
                "FACEBOOK",
                "INSTAGRAM",
                "AUDIENCE_NETWORK"
            ],
            "impressions_with_index": {
                "impressions_text": "100K-200K",
                "impressions_index": 4
            },
            "snapshot": {
                "page_like_count": 30511,
                "page_categories": [
                    "Beauty, cosmetic & personal care"
                ],
                "display_format": "IMAGE",
                "title": "Brighter skin in 14 days",
                "body": "Dermatologist-formulated 15% vitamin C serum for dull, tired skin. Brighter in 14 days or your money back. Now $29.99 (was $45).",
                "link_description": "Free shipping on orders over $35",
                "cta_text": "Learn more",
                "cta_type": "LEARN_MORE",
                "link_url": "https://lumiere-skinlab.example/vitamin-c?utm_source=fb&utm_medium=paid",
                "caption": "lumiere-skinlab.example",
                "images": [
                    {
                        "original_image_url": "https://img.example/lumiere-serum.jpg",
                        "resized_image_url": "https://img.example/lumiere-serum-600.jpg"
                    }
                ]
            },
            "searchTerm": "vitamin c serum",
            "reach_estimate": "80K-120K",
            "landingPage": {
                "status": "ok",
                "storePlatform": "woocommerce",
                "pageType": "product",
                "productTitle": "15% Vitamin C Brightening Serum",
                "price": 29.99,
                "currency": "USD",
                "rating": 4.4,
                "reviewsCount": 612,
                "pageTitle": "Vitamin C Serum | Lumière Skin Lab",
                "fetchedUrl": "https://lumiere-skinlab.example/vitamin-c",
                "sample": true
            }
        },
        {
            "ad_archive_id": "1184500000000005",
            "collation_id": "7300000000000044",
            "collation_count": 2,
            "page_id": "100000000000404",
            "page_name": "StandUp Co",
            "is_active": true,
            "start_date": 1788595200,
            "publisher_platform": [
                "FACEBOOK"
            ],
            "snapshot": {
                "page_categories": [
                    "Furniture"
                ],
                "display_format": "VIDEO",
                "title": "Any desk. Standing in 10 seconds.",
                "body": {
                    "text": "Your back will thank you. The StandUp converter turns any desk into a standing desk in 10 seconds. Free delivery across the US."
                },
                "cta_text": "Shop now",
                "link_url": "https://standup-co.example/converter",
                "caption": "standup-co.example",
                "videos": [
                    {
                        "video_hd_url": "https://video.example/standup-demo.mp4",
                        "video_preview_image_url": "https://img.example/standup-preview.jpg"
                    }
                ]
            },
            "searchTerm": "posture corrector"
        },
        {
            "ad_archive_id": "1184500000000006",
            "page_id": "100000000000505",
            "page_name": "Citizens for Cleaner Parks",
            "is_active": true,
            "start_date": 1780300800,
            "categories": [
                "POLITICAL"
            ],
            "political_countries": [
                "US"
            ],
            "spend": {
                "lower_bound": "1000",
                "upper_bound": "1499"
            },
            "currency": "USD",
            "publisher_platform": [
                "FACEBOOK",
                "INSTAGRAM"
            ],
            "snapshot": {
                "display_format": "IMAGE",
                "body": {
                    "text": "Vote yes on Measure 12 for cleaner city parks."
                },
                "cta_text": "Learn more",
                "link_url": "https://cleanerparks.example/measure-12"
            }
        },
        {
            "ad_archive_id": "1184500000000007",
            "collation_id": "7300000000000066",
            "collation_count": 1,
            "page_id": "100000000000606",
            "page_name": "GlowBox",
            "is_active": true,
            "start_date": 1790150400,
            "publisher_platform": [
                "INSTAGRAM"
            ],
            "snapshot": {
                "display_format": "IMAGE",
                "body": {
                    "text": "New drop: the GlowBox LED mask. Link in bio."
                },
                "cta_text": "Shop now",
                "link_url": "https://glowbox.example/led-mask"
            },
            "searchTerm": "vitamin c serum"
        },
        {
            "ad_archive_id": "1184500000000008",
            "collation_id": "7300000000000077",
            "collation_count": 3,
            "page_id": "100000000000707",
            "page_name": "SnoozeWell",
            "is_active": false,
            "start_date": 1772352000,
            "end_date": 1780128000,
            "publisher_platform": [
                "FACEBOOK",
                "INSTAGRAM"
            ],
            "snapshot": {
                "display_format": "IMAGE",
                "body": {
                    "text": "Fall asleep in 10 minutes with the SnoozeWell weighted eye mask. Free trial for 30 nights."
                },
                "cta_text": "Try it free",
                "link_url": "https://snoozewell.example/mask"
            }
        }
    ],
    "discoveryInput": {},
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("rich_minds/fb-ad-library-winning-ads").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 = {
    "sourceMode": "list",
    "searchTerms": [
        "posture corrector",
        "dog harness",
        "vitamin c serum",
    ],
    "productBrief": "An ergonomic laptop stand for people who work from home — adjustable height, folds flat, aluminium, $49.",
    "maxDiscoveryChargeUsd": 0.5,
    "maxQualified": 100,
    "maxAdsToScan": 150,
    "maxAdsPerSearch": 50,
    "itemsList": [
        {
            "ad_archive_id": "1184500000000001",
            "collation_id": "7300000000000011",
            "collation_count": 12,
            "page_id": "100000000000101",
            "page_name": "Aligna Posture",
            "is_active": True,
            "start_date": 1781942400,
            "end_date": None,
            "publisher_platform": [
                "FACEBOOK",
                "INSTAGRAM",
                "MESSENGER",
            ],
            "categories": ["UNKNOWN"],
            "contains_digital_created_media": False,
            "impressions_with_index": { "impressions_text": None },
            "snapshot": {
                "page_name": "Aligna Posture",
                "page_profile_uri": "https://www.facebook.com/alignaposture.example",
                "page_like_count": 48210,
                "page_categories": ["Health & wellness website"],
                "display_format": "VIDEO",
                "title": "Sit taller in 7 days",
                "body": { "text": "Tired of that 3pm neck ache at your desk? Aligna gently pulls your shoulders back so you sit tall without thinking about it. 50,000+ happy customers. Get 30% OFF today + free shipping." },
                "link_description": "30-day money-back guarantee",
                "cta_text": "Shop now",
                "cta_type": "SHOP_NOW",
                "link_url": "https://aligna.example/posture-corrector?utm_source=facebook&utm_campaign=q3&fbclid=IwAR0x",
                "caption": "ALIGNA.EXAMPLE",
                "images": [],
                "videos": [{
                        "video_hd_url": "https://video.example/aligna-hook-hd.mp4",
                        "video_preview_image_url": "https://img.example/aligna-preview.jpg",
                    }],
                "cards": [],
            },
            "searchTerm": "posture corrector",
            "landingPage": {
                "status": "ok",
                "storePlatform": "shopify",
                "pageType": "product",
                "productTitle": "Aligna Posture Corrector",
                "price": 39.95,
                "currency": "USD",
                "rating": 4.6,
                "reviewsCount": 2184,
                "pageTitle": "Aligna Posture Corrector – Aligna",
                "fetchedUrl": "https://aligna.example/posture-corrector",
                "sample": True,
            },
        },
        {
            "ad_archive_id": "1184500000000002",
            "collation_id": "7300000000000011",
            "collation_count": 12,
            "page_id": "100000000000101",
            "page_name": "Aligna Posture",
            "is_active": True,
            "start_date": 1784361600,
            "publisher_platform": [
                "FACEBOOK",
                "INSTAGRAM",
            ],
            "snapshot": {
                "display_format": "VIDEO",
                "title": "Sit taller in 7 days",
                "body": { "text": "Neck ache at your desk? Aligna pulls your shoulders back. Get 30% OFF today." },
                "cta_text": "Shop now",
                "link_url": "https://aligna.example/posture-corrector?utm_source=facebook&utm_content=v2",
                "caption": "aligna.example",
                "videos": [{ "video_sd_url": "https://video.example/aligna-v2-sd.mp4" }],
            },
            "searchTerm": "posture corrector",
        },
        {
            "adArchiveID": "1184500000000003",
            "collationId": "7300000000000022",
            "collationCount": 6,
            "pageID": "100000000000202",
            "pageName": "Pawtrail",
            "isActive": True,
            "startDateFormatted": "2026-08-01T09:00:00.000Z",
            "publisherPlatform": [
                "facebook",
                "instagram",
            ],
            "containsDigitalCreatedMedia": False,
            "snapshot": {
                "pageProfileUri": "https://www.facebook.com/pawtrail.example",
                "pageLikeCount": 12940,
                "pageCategories": ["Pet supplies"],
                "displayFormat": "CAROUSEL",
                "body": { "text": "My dog pulled like a train until we tried the Pawtrail no-pull harness. Now walks are actually fun. Buy 1, get 1 50% off — this week only." },
                "ctaText": "Shop now",
                "ctaType": "SHOP_NOW",
                "caption": "pawtrail.example",
                "cards": [
                    {
                        "title": "The harness that stops the pull",
                        "body": "My dog pulled like a train until we tried the Pawtrail no-pull harness.",
                        "linkUrl": "https://pawtrail.example/no-pull-harness?utm_source=meta",
                        "originalImageUrl": "https://img.example/pawtrail-card-1.jpg",
                    },
                    {
                        "title": "Fits in 30 seconds",
                        "body": "Two clips, no fuss.",
                        "linkUrl": "https://pawtrail.example/no-pull-harness",
                        "originalImageUrl": "https://img.example/pawtrail-card-2.jpg",
                    },
                ],
            },
            "searchTerm": "dog harness",
        },
        {
            "ad_archive_id": "1184500000000004",
            "collation_id": "7300000000000033",
            "collation_count": 4,
            "page_id": "100000000000303",
            "page_name": "Lumière Skin Lab",
            "is_active": True,
            "start_date": 1784102400,
            "publisher_platform": [
                "FACEBOOK",
                "INSTAGRAM",
                "AUDIENCE_NETWORK",
            ],
            "impressions_with_index": {
                "impressions_text": "100K-200K",
                "impressions_index": 4,
            },
            "snapshot": {
                "page_like_count": 30511,
                "page_categories": ["Beauty, cosmetic & personal care"],
                "display_format": "IMAGE",
                "title": "Brighter skin in 14 days",
                "body": "Dermatologist-formulated 15% vitamin C serum for dull, tired skin. Brighter in 14 days or your money back. Now $29.99 (was $45).",
                "link_description": "Free shipping on orders over $35",
                "cta_text": "Learn more",
                "cta_type": "LEARN_MORE",
                "link_url": "https://lumiere-skinlab.example/vitamin-c?utm_source=fb&utm_medium=paid",
                "caption": "lumiere-skinlab.example",
                "images": [{
                        "original_image_url": "https://img.example/lumiere-serum.jpg",
                        "resized_image_url": "https://img.example/lumiere-serum-600.jpg",
                    }],
            },
            "searchTerm": "vitamin c serum",
            "reach_estimate": "80K-120K",
            "landingPage": {
                "status": "ok",
                "storePlatform": "woocommerce",
                "pageType": "product",
                "productTitle": "15% Vitamin C Brightening Serum",
                "price": 29.99,
                "currency": "USD",
                "rating": 4.4,
                "reviewsCount": 612,
                "pageTitle": "Vitamin C Serum | Lumière Skin Lab",
                "fetchedUrl": "https://lumiere-skinlab.example/vitamin-c",
                "sample": True,
            },
        },
        {
            "ad_archive_id": "1184500000000005",
            "collation_id": "7300000000000044",
            "collation_count": 2,
            "page_id": "100000000000404",
            "page_name": "StandUp Co",
            "is_active": True,
            "start_date": 1788595200,
            "publisher_platform": ["FACEBOOK"],
            "snapshot": {
                "page_categories": ["Furniture"],
                "display_format": "VIDEO",
                "title": "Any desk. Standing in 10 seconds.",
                "body": { "text": "Your back will thank you. The StandUp converter turns any desk into a standing desk in 10 seconds. Free delivery across the US." },
                "cta_text": "Shop now",
                "link_url": "https://standup-co.example/converter",
                "caption": "standup-co.example",
                "videos": [{
                        "video_hd_url": "https://video.example/standup-demo.mp4",
                        "video_preview_image_url": "https://img.example/standup-preview.jpg",
                    }],
            },
            "searchTerm": "posture corrector",
        },
        {
            "ad_archive_id": "1184500000000006",
            "page_id": "100000000000505",
            "page_name": "Citizens for Cleaner Parks",
            "is_active": True,
            "start_date": 1780300800,
            "categories": ["POLITICAL"],
            "political_countries": ["US"],
            "spend": {
                "lower_bound": "1000",
                "upper_bound": "1499",
            },
            "currency": "USD",
            "publisher_platform": [
                "FACEBOOK",
                "INSTAGRAM",
            ],
            "snapshot": {
                "display_format": "IMAGE",
                "body": { "text": "Vote yes on Measure 12 for cleaner city parks." },
                "cta_text": "Learn more",
                "link_url": "https://cleanerparks.example/measure-12",
            },
        },
        {
            "ad_archive_id": "1184500000000007",
            "collation_id": "7300000000000066",
            "collation_count": 1,
            "page_id": "100000000000606",
            "page_name": "GlowBox",
            "is_active": True,
            "start_date": 1790150400,
            "publisher_platform": ["INSTAGRAM"],
            "snapshot": {
                "display_format": "IMAGE",
                "body": { "text": "New drop: the GlowBox LED mask. Link in bio." },
                "cta_text": "Shop now",
                "link_url": "https://glowbox.example/led-mask",
            },
            "searchTerm": "vitamin c serum",
        },
        {
            "ad_archive_id": "1184500000000008",
            "collation_id": "7300000000000077",
            "collation_count": 3,
            "page_id": "100000000000707",
            "page_name": "SnoozeWell",
            "is_active": False,
            "start_date": 1772352000,
            "end_date": 1780128000,
            "publisher_platform": [
                "FACEBOOK",
                "INSTAGRAM",
            ],
            "snapshot": {
                "display_format": "IMAGE",
                "body": { "text": "Fall asleep in 10 minutes with the SnoozeWell weighted eye mask. Free trial for 30 nights." },
                "cta_text": "Try it free",
                "link_url": "https://snoozewell.example/mask",
            },
        },
    ],
    "discoveryInput": {},
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("rich_minds/fb-ad-library-winning-ads").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "sourceMode": "list",
  "searchTerms": [
    "posture corrector",
    "dog harness",
    "vitamin c serum"
  ],
  "productBrief": "An ergonomic laptop stand for people who work from home — adjustable height, folds flat, aluminium, $49.",
  "maxDiscoveryChargeUsd": 0.5,
  "maxQualified": 100,
  "maxAdsToScan": 150,
  "maxAdsPerSearch": 50,
  "itemsList": [
    {
      "ad_archive_id": "1184500000000001",
      "collation_id": "7300000000000011",
      "collation_count": 12,
      "page_id": "100000000000101",
      "page_name": "Aligna Posture",
      "is_active": true,
      "start_date": 1781942400,
      "end_date": null,
      "publisher_platform": [
        "FACEBOOK",
        "INSTAGRAM",
        "MESSENGER"
      ],
      "categories": [
        "UNKNOWN"
      ],
      "contains_digital_created_media": false,
      "impressions_with_index": {
        "impressions_text": null
      },
      "snapshot": {
        "page_name": "Aligna Posture",
        "page_profile_uri": "https://www.facebook.com/alignaposture.example",
        "page_like_count": 48210,
        "page_categories": [
          "Health & wellness website"
        ],
        "display_format": "VIDEO",
        "title": "Sit taller in 7 days",
        "body": {
          "text": "Tired of that 3pm neck ache at your desk? Aligna gently pulls your shoulders back so you sit tall without thinking about it. 50,000+ happy customers. Get 30% OFF today + free shipping."
        },
        "link_description": "30-day money-back guarantee",
        "cta_text": "Shop now",
        "cta_type": "SHOP_NOW",
        "link_url": "https://aligna.example/posture-corrector?utm_source=facebook&utm_campaign=q3&fbclid=IwAR0x",
        "caption": "ALIGNA.EXAMPLE",
        "images": [],
        "videos": [
          {
            "video_hd_url": "https://video.example/aligna-hook-hd.mp4",
            "video_preview_image_url": "https://img.example/aligna-preview.jpg"
          }
        ],
        "cards": []
      },
      "searchTerm": "posture corrector",
      "landingPage": {
        "status": "ok",
        "storePlatform": "shopify",
        "pageType": "product",
        "productTitle": "Aligna Posture Corrector",
        "price": 39.95,
        "currency": "USD",
        "rating": 4.6,
        "reviewsCount": 2184,
        "pageTitle": "Aligna Posture Corrector – Aligna",
        "fetchedUrl": "https://aligna.example/posture-corrector",
        "sample": true
      }
    },
    {
      "ad_archive_id": "1184500000000002",
      "collation_id": "7300000000000011",
      "collation_count": 12,
      "page_id": "100000000000101",
      "page_name": "Aligna Posture",
      "is_active": true,
      "start_date": 1784361600,
      "publisher_platform": [
        "FACEBOOK",
        "INSTAGRAM"
      ],
      "snapshot": {
        "display_format": "VIDEO",
        "title": "Sit taller in 7 days",
        "body": {
          "text": "Neck ache at your desk? Aligna pulls your shoulders back. Get 30% OFF today."
        },
        "cta_text": "Shop now",
        "link_url": "https://aligna.example/posture-corrector?utm_source=facebook&utm_content=v2",
        "caption": "aligna.example",
        "videos": [
          {
            "video_sd_url": "https://video.example/aligna-v2-sd.mp4"
          }
        ]
      },
      "searchTerm": "posture corrector"
    },
    {
      "adArchiveID": "1184500000000003",
      "collationId": "7300000000000022",
      "collationCount": 6,
      "pageID": "100000000000202",
      "pageName": "Pawtrail",
      "isActive": true,
      "startDateFormatted": "2026-08-01T09:00:00.000Z",
      "publisherPlatform": [
        "facebook",
        "instagram"
      ],
      "containsDigitalCreatedMedia": false,
      "snapshot": {
        "pageProfileUri": "https://www.facebook.com/pawtrail.example",
        "pageLikeCount": 12940,
        "pageCategories": [
          "Pet supplies"
        ],
        "displayFormat": "CAROUSEL",
        "body": {
          "text": "My dog pulled like a train until we tried the Pawtrail no-pull harness. Now walks are actually fun. Buy 1, get 1 50% off — this week only."
        },
        "ctaText": "Shop now",
        "ctaType": "SHOP_NOW",
        "caption": "pawtrail.example",
        "cards": [
          {
            "title": "The harness that stops the pull",
            "body": "My dog pulled like a train until we tried the Pawtrail no-pull harness.",
            "linkUrl": "https://pawtrail.example/no-pull-harness?utm_source=meta",
            "originalImageUrl": "https://img.example/pawtrail-card-1.jpg"
          },
          {
            "title": "Fits in 30 seconds",
            "body": "Two clips, no fuss.",
            "linkUrl": "https://pawtrail.example/no-pull-harness",
            "originalImageUrl": "https://img.example/pawtrail-card-2.jpg"
          }
        ]
      },
      "searchTerm": "dog harness"
    },
    {
      "ad_archive_id": "1184500000000004",
      "collation_id": "7300000000000033",
      "collation_count": 4,
      "page_id": "100000000000303",
      "page_name": "Lumière Skin Lab",
      "is_active": true,
      "start_date": 1784102400,
      "publisher_platform": [
        "FACEBOOK",
        "INSTAGRAM",
        "AUDIENCE_NETWORK"
      ],
      "impressions_with_index": {
        "impressions_text": "100K-200K",
        "impressions_index": 4
      },
      "snapshot": {
        "page_like_count": 30511,
        "page_categories": [
          "Beauty, cosmetic & personal care"
        ],
        "display_format": "IMAGE",
        "title": "Brighter skin in 14 days",
        "body": "Dermatologist-formulated 15% vitamin C serum for dull, tired skin. Brighter in 14 days or your money back. Now $29.99 (was $45).",
        "link_description": "Free shipping on orders over $35",
        "cta_text": "Learn more",
        "cta_type": "LEARN_MORE",
        "link_url": "https://lumiere-skinlab.example/vitamin-c?utm_source=fb&utm_medium=paid",
        "caption": "lumiere-skinlab.example",
        "images": [
          {
            "original_image_url": "https://img.example/lumiere-serum.jpg",
            "resized_image_url": "https://img.example/lumiere-serum-600.jpg"
          }
        ]
      },
      "searchTerm": "vitamin c serum",
      "reach_estimate": "80K-120K",
      "landingPage": {
        "status": "ok",
        "storePlatform": "woocommerce",
        "pageType": "product",
        "productTitle": "15% Vitamin C Brightening Serum",
        "price": 29.99,
        "currency": "USD",
        "rating": 4.4,
        "reviewsCount": 612,
        "pageTitle": "Vitamin C Serum | Lumière Skin Lab",
        "fetchedUrl": "https://lumiere-skinlab.example/vitamin-c",
        "sample": true
      }
    },
    {
      "ad_archive_id": "1184500000000005",
      "collation_id": "7300000000000044",
      "collation_count": 2,
      "page_id": "100000000000404",
      "page_name": "StandUp Co",
      "is_active": true,
      "start_date": 1788595200,
      "publisher_platform": [
        "FACEBOOK"
      ],
      "snapshot": {
        "page_categories": [
          "Furniture"
        ],
        "display_format": "VIDEO",
        "title": "Any desk. Standing in 10 seconds.",
        "body": {
          "text": "Your back will thank you. The StandUp converter turns any desk into a standing desk in 10 seconds. Free delivery across the US."
        },
        "cta_text": "Shop now",
        "link_url": "https://standup-co.example/converter",
        "caption": "standup-co.example",
        "videos": [
          {
            "video_hd_url": "https://video.example/standup-demo.mp4",
            "video_preview_image_url": "https://img.example/standup-preview.jpg"
          }
        ]
      },
      "searchTerm": "posture corrector"
    },
    {
      "ad_archive_id": "1184500000000006",
      "page_id": "100000000000505",
      "page_name": "Citizens for Cleaner Parks",
      "is_active": true,
      "start_date": 1780300800,
      "categories": [
        "POLITICAL"
      ],
      "political_countries": [
        "US"
      ],
      "spend": {
        "lower_bound": "1000",
        "upper_bound": "1499"
      },
      "currency": "USD",
      "publisher_platform": [
        "FACEBOOK",
        "INSTAGRAM"
      ],
      "snapshot": {
        "display_format": "IMAGE",
        "body": {
          "text": "Vote yes on Measure 12 for cleaner city parks."
        },
        "cta_text": "Learn more",
        "link_url": "https://cleanerparks.example/measure-12"
      }
    },
    {
      "ad_archive_id": "1184500000000007",
      "collation_id": "7300000000000066",
      "collation_count": 1,
      "page_id": "100000000000606",
      "page_name": "GlowBox",
      "is_active": true,
      "start_date": 1790150400,
      "publisher_platform": [
        "INSTAGRAM"
      ],
      "snapshot": {
        "display_format": "IMAGE",
        "body": {
          "text": "New drop: the GlowBox LED mask. Link in bio."
        },
        "cta_text": "Shop now",
        "link_url": "https://glowbox.example/led-mask"
      },
      "searchTerm": "vitamin c serum"
    },
    {
      "ad_archive_id": "1184500000000008",
      "collation_id": "7300000000000077",
      "collation_count": 3,
      "page_id": "100000000000707",
      "page_name": "SnoozeWell",
      "is_active": false,
      "start_date": 1772352000,
      "end_date": 1780128000,
      "publisher_platform": [
        "FACEBOOK",
        "INSTAGRAM"
      ],
      "snapshot": {
        "display_format": "IMAGE",
        "body": {
          "text": "Fall asleep in 10 minutes with the SnoozeWell weighted eye mask. Free trial for 30 nights."
        },
        "cta_text": "Try it free",
        "link_url": "https://snoozewell.example/mask"
      }
    }
  ],
  "discoveryInput": {},
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call rich_minds/fb-ad-library-winning-ads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rich_minds/fb-ad-library-winning-ads"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/F1Wj2lL3lq8FgjLql/builds/B5cxu0JC5c3MVOZy0/openapi.json
