Facebook Ad Library Winning Ads Finder: AI creative breakdown on the Apify Store →

How to find winning Facebook ads in the Meta Ad Library (and what makes them work)

Tutorial article for the Apify blog guest program, dev.to, Medium, Hashnode — drafted with the listing, refreshed with the first real run by /actor-marketing; the owner publishes it and records the URL in brief.json → marketing.links. Store: https://apify.com/rich_minds/fb-ad-library-winning-ads

The problem

Every DTC brand, dropshipper and agency media buyer does the same Monday ritual: open the Facebook Ad Library, type a competitor or a product, scroll through hundreds of ads — most of them the same creative in 12 variants, some of them political, many started yesterday. The ads that matter are the ones that have been running for weeks: nobody keeps paying for an ad that loses money. So you copy start dates into a spreadsheet, collapse the duplicates by eye, compute how long each ad has run, paste the hook and the offer into a swipe file and brainstorm how to adapt the angle for your own product. For 10 competitors that is two to three hours a week.

The Store's Ad Library scrapers help with the first step only: curious_coder/facebook-ads-library-scraper (5,855 users a month, $0.00075 per ad) returns one raw row per variant. The sorting, the scoring and the analysis stay manual.

Step by step

  1. Try the demo. Open Facebook Ad Library Winning Ads Finder: AI creative breakdown on the Apify Store and click Try it. The form is pre-filled with 8 sample Ad Library records; the run takes about a second and costs nothing. Variants of the same creative become one row, political, brand-new and stopped ads are dropped, and the winners come back best first (docs/img/shortlist.svg) — the sample Aligna Posture ad leads: 98 days running, 12 variants, 3 placements, winner score 85.
  2. Search for real. Switch Where do the ads come from? to the live search and type your terms:
   {"sourceMode": "actor", "searchTerms": ["posture corrector", "dog harness", "vitamin c serum"],
    "country": "US", "maxAdsToScan": 150, "maxDiscoveryChargeUsd": 0.5, "enableAi": true,
    "productBrief": "An ergonomic laptop stand for people who work from home — adjustable height, folds flat, aluminium, $49."}

The Actor runs the Ad Library scraper on your account (150 ads ≈ $0.11), collapses variants by Meta's collation id, drops young (< 7 days), stopped and political ads for free and scores the rest.

  1. Read the Shortlist. Each row: winner score 0–100 with reasons ("running 98 days (+40)", "12 variants of the creative (+20)"), the offer the copy makes ("30% OFF · free shipping · 30-day money-back"), the landing page without tracking parameters and the hook.
  2. Open the Creative brief view. With AI on, every ad gets the angle (problem-solution, social proof, UGC …), the audience it appears aimed at, the emotional trigger, up to three quotes copied verbatim from the ad — and a rewrite of the angle for your product that never reuses the competitor's brand, numbers or claims.
  3. Export or connect. CSV / Excel from the dataset, a webhook to Slack or your CRM, or the Google Sheets integration.

Reading the results: what makes an ad a "winner"

Meta publishes spend and impressions only for political and EU ads, so for a commercial competitor the public signals are behavioural: how long the advertiser keeps paying, how many variants they built, and where they place it. The winner score adds them up, and every row lists the reasons so you can disagree with it:

SignalPoints
Days runningup to 40
Still active15
Variants of the same creativeup to 20
Two or more placements (Facebook, Instagram, Messenger, Audience Network)10
Impressions bucket (only where Meta shows one)up to 15

The default minWinnerScore is 40 — an ad has to have run for a while and show one more sign of scaling. Days running is a proxy for profit, not a performance figure: a brand with a big budget can keep a mediocre ad alive. That is why the AI breakdown quotes the ad itself instead of guessing results, and why the fit score is measured against your product brief, not a generic "quality" number.

Three habits that make the output useful:

What a run costs

The source bills its own rows on your account: 1,000 ads scanned ≈ $0.75. Here you pay per qualified ad only: the first 25 are free, then $0.003 (rules) or $0.012 with the AI breakdown, plus ≈ $0.003 of AI tokens with the default model. 1,000 scanned → 150 qualified with AI: $0.75 + 125 × $0.012 + ≈ $0.45 = $2.70, about $0.018 per winning ad — variants, dead, political and duplicate ads cost nothing.

Automate it

Schedule the same input weekly with onlyNewAds: true (the default) and your address in notifyEmail: every Monday the digest lists only the new long-running ads, and you pay only for those.

from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("rich_minds/fb-ad-library-winning-ads").call(run_input={
    "sourceMode": "actor",
    "competitorPages": ["https://www.facebook.com/competitor-one", "https://www.facebook.com/competitor-two"],
    "minDaysRunning": 14,
    "maxDiscoveryChargeUsd": 0.5,
})
for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(ad["advertiserName"], ad["daysRunning"], ad["creative"]["hook"])

Try it

The demo is pre-filled and free on any plan; your first 25 qualified ads are free after that: https://apify.com/rich_minds/fb-ad-library-winning-ads — and if it saves you a Monday, a review on the Store helps other media buyers find it.

Facebook Ad Library Winning Ads Finder: AI creative breakdown on the Apify Store →