Facebook & Instagram Ads: Active Advertiser Leads avatar

Facebook & Instagram Ads: Active Advertiser Leads

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Facebook & Instagram Ads: Active Advertiser Leads

Facebook & Instagram Ads: Active Advertiser Leads

Find businesses actively running Facebook & Instagram ads, with emails, phones, websites, ad and video activity, lead scores, and the option to get only what's new each run.

Pricing

from $1.00 / 1,000 results

Rating

5.0

(1)

Developer

John.Automates

John.Automates

Maintained by Community

Actor stats

0

Bookmarked

5

Total users

1

Monthly active users

25 days ago

Last modified

Share

Facebook & Instagram Ads Lead Finder

Find businesses actively running Facebook and Instagram ads, and get everything you need to pitch them — one row per business, not per ad.

Point it at a niche and a country. It scans the Meta Ad Library, works out which advertisers are actually worth contacting, digs up their contact details, and links you straight to their live ads so you can check any lead yourself.

What you get

One row per business. Export to CSV / JSON / Excel, or push straight into Instantly, Smartlead, Apollo, HubSpot or Pipedrive.

Every row includes
BusinessName, website, domain, Facebook Page
ContactEmail, phone, Instagram, TikTok, LinkedIn, Facebook, contact page
Ad activityActive ads, video ads, new ads in the last 7 / 30 / 90 days, creative velocity, how long they have been advertising
ScoresAd activity 0–100, UGC-buyer potential 0–100, contactability, and a plain-English reason to reach out now
ProofA link to every live ad they are running, plus five representative ads with copy, CTA and landing page
HistoryWhether they are new to you, when you first saw them, and what they have launched since your last scan

How it works

  1. Searches the public Meta Ad Library for active ads matching each of your search queries.
  2. Groups every ad by advertiser (their Facebook Page), merging and de-duplicating across all your queries so each business appears once.
  3. Calculates activity per advertiser: how many active ads, how fast they are adding new ones, how much of it is video, and how long they have been running.
  4. Drops any advertiser below your activity, recency or video thresholds — before doing any expensive work.
  5. Works out each remaining advertiser's own website from their ad destinations, and skips anything on your exclusion list.
  6. Visits the surviving websites and pulls public email, phone and social links.
  7. Checks each advertiser against your own history of previously delivered leads, labelling them new or returning.
  8. Scores every advertiser, attaches evidence links, and writes rows to the dataset as they finish.

Who it's for

Everyone in the list is already paying to run ads: budget exists, someone owns paid social, and they are actively buying creative. That is a warm list, not a scrape.

WhoWhat they get
Paid media & marketing agenciesOutbound lists of businesses with proven advertising activity, contactable today
UGC creators & video editorsBrands demonstrably buying video creative — no need to sell them on the format
CRO & landing-page agenciesActive advertisers plus the landing pages and CTAs they are driving traffic to
Freelance marketersA warm pipeline without hours spent scrolling the Ad Library
B2B prospectorsCompanies qualified by observable behaviour rather than firmographics

⚡ Actively maintained — patched quickly whenever Meta changes its Ad Library. Latest release, September 2026: video inside carousel and catalog ads is now counted correctly · Ad Library proof links on every lead · separate ad-activity and UGC-buyer scores · filters for recent ads, video ads, email and excluded domains · recurring runs that return only what is new.


Why it beats a generic Ad Library scraper

A generic Ad Library scraperThis actor
Hundreds of ad rows, many from the same advertiserOne row per business
Every advertiser it findsOnly those meeting your activity, recency and video thresholds
No contact detailsEmail, phone, website and socials from the advertiser's own site
No prioritisationTwo 0–100 scores plus a plain-English reason to reach out
No proofAd Library links to the advertiser and to individual ads
The same list every runOnly what is new since your last scan

The Meta Ad Library extraction is built in, so no other paid Actor or scraping service is required.


Example output

A complete record, with every field the Actor produces. This is one real row, not an abridged illustration.

{
"advertiserName": "GlowLab Skincare",
"facebookPageId": "123456789",
"facebookPageUrl": "https://www.facebook.com/123456789",
"adLibraryPageUrl": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&view_all_page_id=123456789",
"website": "https://glowlabskincare.com",
"domain": "glowlabskincare.com",
"emails": [
"hello@glowlabskincare.com"
],
"phones": [
"+15551234567"
],
"instagram": "https://www.instagram.com/glowlabskincare",
"linkedin": null,
"tiktok": "https://www.tiktok.com/@glowlabskincare",
"facebook": null,
"contactPageUrl": "https://glowlabskincare.com/contact",
"activeAdCount": 19,
"imageAdCount": 8,
"videoAdCount": 11,
"carouselAdCount": 0,
"videoShare": 0.579,
"adsStartedLast7Days": 5,
"adsStartedLast30Days": 8,
"adsStartedLast90Days": 8,
"videoAdsStartedLast30Days": 5,
"oldestActiveAdDate": "2026-02-09",
"newestActiveAdDate": "2026-09-02",
"creativeVelocity": "MEDIUM",
"advertiserStatus": "NEW",
"firstSeenAt": null,
"lastSeenAt": null,
"adsStartedSinceLastScan": 0,
"ctas": [
"Shop Now",
"Learn More"
],
"landingPages": [
"https://glowlabskincare.com/products/vitamin-c-serum?utm_source=fb",
"https://glowlabskincare.com/collections/bestsellers"
],
"landingDomains": [
"glowlabskincare.com"
],
"platforms": [
"FACEBOOK",
"INSTAGRAM"
],
"queriesMatched": [
"skincare"
],
"opportunityScore": 80,
"adActivityScore": 77,
"ugcBuyerScore": 92,
"contactability": "EMAIL",
"signals": [
"NEW_ADVERTISER",
"LAUNCHING_NEW_VIDEO",
"VIDEO_BUYER",
"LONG_RUNNING",
"HAS_EMAIL"
],
"opportunityReason": "High-opportunity advertiser: first time this advertiser has appeared in your scans, 8 new ads started in the last 30 days, 5 new video creatives among them, 19 active ads seen in this scan, their oldest active ad has been running 213 days, and a public business email was found.",
"sampleAds": [
{
"libraryId": "1201948300000001",
"adLibraryUrl": "https://www.facebook.com/ads/library/?id=1201948300000001",
"startDate": "2026-09-02",
"text": "I tried this vitamin C serum for 30 days and my dark spots faded. Here is the before and after.",
"cta": "Shop Now",
"destinationUrl": "https://glowlabskincare.com/products/vitamin-c-serum?utm_source=fb",
"format": "VIDEO",
"hasVideo": true
},
{
"libraryId": "1201948300000002",
"adLibraryUrl": "https://www.facebook.com/ads/library/?id=1201948300000002",
"startDate": "2026-09-02",
"text": "Three dermatologists explain why vitamin C belongs in your morning routine.",
"cta": "Shop Now",
"destinationUrl": "https://glowlabskincare.com/products/vitamin-c-serum?utm_source=fb",
"format": "VIDEO",
"hasVideo": true
},
{
"libraryId": "1201948300000009",
"adLibraryUrl": "https://www.facebook.com/ads/library/?id=1201948300000009",
"startDate": "2026-02-09",
"text": "The full routine, step by step.",
"cta": "Shop Now",
"destinationUrl": "https://glowlabskincare.com/products/vitamin-c-serum?utm_source=fb",
"format": "CAROUSEL",
"hasVideo": true
},
{
"libraryId": "1201948300000010",
"adLibraryUrl": "https://www.facebook.com/ads/library/?id=1201948300000010",
"startDate": "2026-02-09",
"text": "The full routine, step by step.",
"cta": "Shop Now",
"destinationUrl": "https://glowlabskincare.com/products/vitamin-c-serum?utm_source=fb",
"format": "CAROUSEL",
"hasVideo": true
},
{
"libraryId": "1201948300000003",
"adLibraryUrl": "https://www.facebook.com/ads/library/?id=1201948300000003",
"startDate": "2026-09-02",
"text": "Three dermatologists explain why vitamin C belongs in your morning routine.",
"cta": "Shop Now",
"destinationUrl": "https://glowlabskincare.com/products/vitamin-c-serum?utm_source=fb",
"format": "VIDEO",
"hasVideo": true
}
]
}

Nullable fields come back as null rather than being omitted, so a CSV export has consistent columns. See Output fields for what each one means.


⚠️ Important: this is not ad-spend data

Active ad count is not estimated ad spend. This actor counts how many distinct ads an advertiser currently has running in the Meta Ad Library. It does not know, estimate, or imply how much money any advertiser is spending. Treat activeAdCount, videoAdCount and creativeVelocity as signals of advertising activity, not budget. Nothing in the output will ever tell you a business is "scaling" or "increasing spend", because that is not something public data supports.

Counts are also scoped to your search. activeAdCount is the number of active ads found for your search queries, not the advertiser's full Ad Library total. An advertiser running 200 ads may show 12 here if that is how many matched your keywords. Use adLibraryPageUrl to see their real, complete list. This is why the reason text says "seen in this scan".


Input

{
"searchQueries": ["skincare", "serum"],
"country": "US",
"minActiveAds": 5,
"minVideoAds": 3,
"requireEmail": true
}
FieldTypeDefaultWhat it does
searchQueriesstring[]["skincare"]Keywords to search. Use several close variations (skincare, skin care, serum, acne) to widen coverage of a niche; results are merged and de-duplicated by advertiser.
countrystringUSCountry to search, picked from a dropdown (matches the country selector on the public Ad Library site).
maxAdsinteger300The budget, and the real limiter. How many ads the run may scan across all queries. Most advertisers surface only one or two ads in a shallow scan and so fall below minActiveAds, so budget about 12x your lead target: 25 leads needs ~300 ads, 100 leads needs ~1200. Roughly one minute per 300 ads.
maxAdvertisersinteger25The target. The run stops once this many qualified advertisers are found. Raising it without raising maxAds will not get you more leads — see the note below.
minActiveAdsinteger3Only advertisers with at least this many active ads found during the scan become leads.

These two knobs work together. maxAdvertisers is what you want; maxAds is what you let the run spend to find it. If the budget runs out first you get fewer leads than you asked for, so the Actor warns you at the start when they look mismatched, and reports the measured rate for your niche at the end:

Yield: 34 advertiser(s) qualified from 300 ads scanned (0.113 per ad), short of your maxAdvertisers=100 target. At this niche's rate, reaching 100 would take about 885 ads: set maxAds=885 next run.

Use that number rather than guessing — the rate varies by niche, by minActiveAds, and (with ONLY_NEW) grows as your history builds up.

Advanced filters

All optional. The first two are evaluated before any website is crawled, so they cut run time and cost as well as narrowing results.

FieldTypeDefaultWhat it does
minAdsStartedLast30Daysinteger0Only keep advertisers that launched at least this many new ads in the last 30 days. The strongest timeliness filter — it targets accounts someone is actively working right now.
minVideoAdsinteger0Only keep advertisers running at least this many active video ads (including video inside carousel and catalog formats). The qualifier for UGC, video-editing and creative pitches.
requireEmailbooleanfalseDrop advertisers where no public email was found. Checked after the website crawl, so it trims results rather than making the run cheaper.
excludeDomainsstring[][]Domains to skip — existing customers, or advertisers you have already contacted. Enter bare domains (example.com); www and subdomains match automatically. Excluded advertisers are dropped before their website is crawled.

Recurring runs

FieldTypeDefaultWhat it does
historyModeenumTRACKTRACK labels every advertiser NEW or RETURNING and returns everything. ONLY_NEW returns only advertisers no previous run delivered — the setting for a weekly schedule. OFF disables cross-run memory.

History is stored in your own Apify account and never shared with anyone else. Advertisers are remembered by Facebook Page ID for as long as you keep running the Actor — there is no expiry window, so NEW always means genuinely new to you rather than something the Actor forgot. An advertiser is only remembered once a row has actually been delivered, so a lead that requireEmail filtered out this week can still arrive as new next week once an email is found.

Contact enrichment

FieldTypeDefaultWhat it does
includeContactEnrichmentbooleantrueVisit each qualifying advertiser's website for public contact info. Turn off to run faster and cheaper (Meta data only).
maxWebsitePagesPerLeadinteger4Max pages checked per advertiser website (home, contact, about, team).

Example — a focused UGC prospecting run:

{
"searchQueries": ["skincare", "serum", "acne treatment"],
"country": "US",
"minActiveAds": 5,
"minVideoAds": 3,
"minAdsStartedLast30Days": 4,
"requireEmail": true
}

Skincare advertisers in the US running at least 5 ads, at least 3 of them video, who launched at least 4 new ads in the last month, and where an email was found.


Output fields

Every record contains every field below. Nullable fields are null when not found.

Business

FieldTypeDescription
advertiserNamestringAdvertiser / Facebook Page name
facebookPageId / facebookPageUrlstring | nullFacebook Page ID and link
adLibraryPageUrlstring | nullEvery active ad this advertiser is running — the verification link
website / domainstring | nullAdvertiser's own website, discovered from their ads
emails / phonesstring[]Public contact details found on the website
instagram / linkedin / tiktok / facebookstring | nullSocial profile links found on the website
contactPageUrlstring | nullThe page the contact info was found on

Advertising activity

FieldTypeDescription
activeAdCountintActive ads found during the scan (scoped to your queries — see the note above)
videoAdCountintActive ads carrying video, including video inside carousel and catalog formats
imageAdCount / carouselAdCountintActive ads by non-video format
videoSharenumberShare (0 to 1) of active ads that carry video
adsStartedLast7Days / adsStartedLast30Days / adsStartedLast90DaysintNew ads started in each window
videoAdsStartedLast30DaysintNew video creatives launched in the last 30 days
oldestActiveAdDate / newestActiveAdDatestringDate range of active ads
creativeVelocityenumNONE | LOW | MEDIUM | HIGH | VERY_HIGH
ctasstring[]Unique call-to-action button texts used
landingPages / landingDomainsstring[]Sample ad destination URLs / all unique destination domains
platformsstring[]Where the ads run, e.g. FACEBOOK, INSTAGRAM
queriesMatchedstring[]Which of your search queries surfaced this advertiser

Recurring-run intelligence

FieldTypeDescription
advertiserStatusenumNEW (no previous run delivered them) | RETURNING | UNKNOWN (untrackable) | null when history is off
firstSeenAtstring | nullFirst run that delivered this advertiser
lastSeenAtstring | nullPrevious run that delivered them
adsStartedSinceLastScanint | nullActive ads that started after your previous scan

What this deliberately does not claim. Only set membership is tracked — whether you have been given this advertiser before. There is no SCALING or DECLINING status, because ad counts here are scoped to whatever your search queries surfaced, so a difference between two runs would mostly measure a change in your query list rather than a change at the advertiser. adsStartedSinceLastScan is counted from each ad's own start date rather than from a difference of totals, so it undercounts rather than overstates.

Scoring

FieldTypeDescription
opportunityScoreint0–100 headline score, the default sort
adActivityScoreint0–100: how active and committed an advertiser this is
ugcBuyerScoreint0–100: how much video creative they are demonstrably buying
contactabilityenumNONE | SOCIAL | PHONE | EMAIL
signalsstring[]Filterable reason tokens, most-discriminating first
opportunityReasonstringPlain-English explanation

Evidence

FieldTypeDescription
sampleAdsarrayA representative mix of their active ads — each with adLibraryUrl, startDate, truncated text, cta, destinationUrl, format, hasVideo

Sample ads are deliberately a mix, not just the newest: the 2 most recent (what they are testing right now, your pitch hook), the 2 longest-running (what has survived for them, the closest thing public data offers to a performance signal), and their latest video creative.

Example rows

The same first advertiser as above, alongside two others, trimmed to the columns you would sort on. One is new to you and two have been seen before. The data is illustrative, but every score, signal and reason was produced by the actual scoring code:

[
{
"advertiserName": "GlowLab Skincare",
"website": "https://glowlabskincare.com",
"emails": [
"hello@glowlabskincare.com"
],
"phones": [
"+15551234567"
],
"activeAdCount": 19,
"videoAdCount": 11,
"adsStartedLast30Days": 8,
"videoAdsStartedLast30Days": 5,
"creativeVelocity": "MEDIUM",
"advertiserStatus": "NEW",
"lastSeenAt": null,
"adsStartedSinceLastScan": 0,
"opportunityScore": 80,
"adActivityScore": 77,
"ugcBuyerScore": 92,
"contactability": "EMAIL",
"signals": [
"NEW_ADVERTISER",
"LAUNCHING_NEW_VIDEO",
"VIDEO_BUYER",
"LONG_RUNNING",
"HAS_EMAIL"
],
"opportunityReason": "High-opportunity advertiser: first time this advertiser has appeared in your scans, 8 new ads started in the last 30 days, 5 new video creatives among them, 19 active ads seen in this scan, their oldest active ad has been running 213 days, and a public business email was found."
},
{
"advertiserName": "Sunrise Botanicals",
"website": "https://sunrisebotanicals.co",
"emails": [],
"phones": [
"+15559876543"
],
"activeAdCount": 12,
"videoAdCount": 7,
"adsStartedLast30Days": 6,
"videoAdsStartedLast30Days": 3,
"creativeVelocity": "MEDIUM",
"advertiserStatus": "RETURNING",
"lastSeenAt": "2026-09-01T09:04:32.000Z",
"adsStartedSinceLastScan": 3,
"opportunityScore": 58,
"adActivityScore": 59,
"ugcBuyerScore": 66,
"contactability": "PHONE",
"signals": [
"LAUNCHING_NEW_VIDEO",
"LONG_RUNNING"
],
"opportunityReason": "Medium-opportunity advertiser: 3 new ads started since your last scan on 2026-09-01, 6 new ads started in the last 30 days, 3 new video creatives among them, 12 active ads seen in this scan, their oldest active ad has been running 97 days, and a public phone number was found (no email)."
},
{
"advertiserName": "Pure Radiance Co.",
"website": null,
"emails": [],
"phones": [],
"activeAdCount": 3,
"videoAdCount": 0,
"adsStartedLast30Days": 0,
"videoAdsStartedLast30Days": 0,
"creativeVelocity": "NONE",
"advertiserStatus": "RETURNING",
"lastSeenAt": "2026-09-01T09:04:32.000Z",
"adsStartedSinceLastScan": 0,
"opportunityScore": 21,
"adActivityScore": 25,
"ugcBuyerScore": 0,
"contactability": "NONE",
"signals": [
"LONG_RUNNING"
],
"opportunityReason": "Low-opportunity advertiser: 3 active ads seen in this scan, their oldest active ad has been running 122 days, and no public contact info was found yet."
}
]

Row 1 is NEW, so NEW_ADVERTISER leads its signals and the reason opens with it. Row 2 has been seen before, so it reports what changed since: 3 new ads started since your last scan on 2026-09-01.


How scoring works

All deterministic, no AI involved. Every point is traceable to a rule, so scores are reproducible and explainable.

adActivityScore — is this an active, committed advertiser?

SignalWeightRewards
Recent ad launches (30 days)45Accounts someone is actively working right now
Active ad volume35Scale of current advertising
Longevity of oldest active ad20A sustained programme, not a one-week test

Recent launches outrank raw volume on purpose: an advertiser who launched ads this month is a timely conversation, and volume is the number most affected by how your keywords happened to match.

ugcBuyerScore — are they demonstrably buying video creative?

SignalWeightRewards
New video creatives (30 days)50The recurring purchase a creator or editor actually sells into
Active video ad count30An existing video library and production budget
Video mix20A healthy share of video, scored as a plateau rather than "more is always better"

This score rewards video usage rather than the absence of it. A business already running and refreshing video has proven it has a creative budget, that someone owns paid social, and that it buys video — you do not have to sell them on the format, only on yourself. A business running zero video ads has proven none of those things.

Two deliberate limits. The video-mix component plateaus instead of climbing to 100%, because a 60%-video advertiser is not meaningfully a worse prospect than an 85%-video one, and a 100%-video mix usually means automated catalog feeds rather than produced creative. And a high score means demonstrated buying, not an open slot — public data cannot tell you whether an advertiser already has an agency or a creator roster.

opportunityScore — the headline sort

adActivityScore plus a bonus for being reachable (email 15, phone 8, social 5). Contactability is a bonus rather than a core component so that a business whose email sits behind a JavaScript form is not demoted for a scraping limitation.

  • 70 to 100 (High-opportunity): heavy, current ad activity and reachable. Your strongest prospects.
  • 40 to 69 (Medium-opportunity): solid activity, worth a look.
  • 0 to 39 (Low-opportunity): lighter or older activity. Kept in the dataset so you can decide.

Sorting tip: sort by opportunityScore for general outbound, or by ugcBuyerScore for UGC, video-editing and creative pitches. They rank differently on purpose.

signals

TokenMeaning
NEW_ADVERTISERNo previous run of yours delivered this advertiser
HIGH_VELOCITY10+ new ads in the last 30 days
LAUNCHING_NEW_VIDEOAt least one new video creative in the last 30 days
VIDEO_BUYER10+ active video ads
HIGH_AD_VOLUME20+ active ads found
LONG_RUNNINGOldest active ad running 60+ days
HAS_EMAILA public business email was found

Creative velocity

Every advertiser gets a creativeVelocity rating based on how many new ads they started in the last 30 days, a quick read on how actively they are testing new creative.

VelocityWhat it meansWhy it matters
VERY_HIGH20+ new ads in the last 30 daysConstantly testing, always hungry for fresh creative
HIGH10 to 19 new ads in the last 30 daysActive, ongoing testing cadence
MEDIUM4 to 9 new ads in the last 30 daysSteady but modest testing
LOW1 to 3 new ads in the last 30 daysSlow cadence
NONE0 new ads in the last 30 daysRunning the same creative for a while

The weekly workflow

The setup this is built for:

  1. Configure a run for your niche, with whatever filters you want.
  2. Set historyMode to ONLY_NEW.
  3. Schedule it weekly in Apify.

Each week you receive only the advertisers that have appeared since your last scan. A week with nothing new returns zero rows, and the log says so explicitly — that is the expected result, not a failure.

If you want to see everything again, switch historyMode back to TRACK; nothing is lost, and returning advertisers still carry lastSeenAt and adsStartedSinceLastScan so you can see what changed.


How fast and how big

  • The Meta scan is the long phase. Meta returns about 10 ads per request and the actor pauses between requests to avoid being rate-limited, so expect roughly 1 minute per 300 ads. Progress is logged every 10 pages, so you can always see it moving.
  • The defaults are sized for a quick first run — about a minute of scanning, enough to see exactly what the output looks like. For serious prospecting raise maxAds to 1000–3000 and maxAdvertisers to 100+, and expect several minutes.
  • Enrichment adds a couple of minutes for a batch of 100 leads, since it visits each one's real website. Progress is logged as it goes. Turn includeContactEnrichment off to skip it entirely.
  • The run stops once maxAdvertisers qualified leads are found and a meaningful ad sample has been scanned, or when maxAds raw ads have been scanned — whichever comes first.
  • Rows are written to the dataset as they finish, strongest advertisers first, so an interrupted run still delivers its best leads.
  • Every website is only ever visited once per run, and results are reused for a while across runs, even if the same brand matches several of your search queries.
  • Runtime scales with maxAds; cost scales with how many advertisers pass your filters. Lowering maxAds is the fastest way to shorten a run; raising minActiveAds, minAdsStartedLast30Days or minVideoAds is the fastest way to cut enrichment cost.

FAQ

I'm a UGC creator, not an agency. Is this actually for me? Yes, and there is a specific way to run it. Set minVideoAds to 3 or more and sort your results by ugcBuyerScore. That gives you brands already spending money on video creative and refreshing it regularly — they have a budget for what you make, someone in-house who manages it, and a continuing need for new creative. You are not selling them on the idea of video, just on yourself.

Why doesn't a brand with zero video ads score highly for UGC? Because "they have no video" is a guess about what a business might want, not evidence of what it buys. A brand running and refreshing video every month has demonstrated a creative budget, an owner for paid social, and repeat purchasing. A brand with none of that may simply not buy video at all. If you specifically want the whitespace pitch, sort by adActivityScore and filter for a low videoShare — the data is all there.

How do I stop getting the same advertisers every week? Set historyMode to ONLY_NEW and schedule the run. The actor remembers, in your own account, which advertisers it has already delivered to you, and returns only ones it has not. There is no expiry: an advertiser you received a year ago will not come back as new.

Why does the actor say an advertiser is NEW when they have clearly been advertising for years? NEW means new to your scans, not new to Meta. It is a statement about what this actor has already handed you, nothing more. An advertiser running ads since 2019 will still be NEW the first time your search surfaces them.

Is my history shared with other users of this actor? No. It is stored in a key-value store in your own Apify account, created the first time you run the actor. No other user can read it, and it is never sent anywhere.

Does this tell me how much a business is spending on ads? No. activeAdCount, videoAdCount and creativeVelocity measure ad activity — how many ads are running and how often new ones appear — not budget. Meta's Ad Library does not expose spend for ordinary commercial advertisers, and this actor never estimates or implies one.

Why does activeAdCount look lower than what I see in the Ad Library? Because it counts ads that matched your search queries, not the advertiser's entire library. Open adLibraryPageUrl on any row to see their complete active list. Adding more query variations raises the counts you see.

The log went quiet for minutes. Is it stuck? Almost certainly not. The Meta scan makes one request per ~10 ads, pausing between each to avoid rate limits, so a large maxAds means a lot of requests. It logs progress every 10 pages (Meta scan progress for "skincare": 20 pages, 195/300 unique ads collected), so if you see those ticking up it is working. Individual requests are capped at 30 seconds and retried, so a genuine stall surfaces as a warning rather than silence.

Why did I get fewer leads than maxAdvertisers? maxAdvertisers is a ceiling, not a target. If fewer advertisers meet your filters, you get fewer rows. Lower minActiveAds, clear the advanced filters, or add more searchQueries.

I set several filters and got zero results. That is a valid outcome for a narrow niche with strict filters, not a failure — the run log says so explicitly. requireEmail combined with a high minVideoAds is the most common cause. Loosen one at a time.

A lead has no email or phone. Why keep it? Not every business publishes contact info, but their ad activity is still a real signal, and contactability tells you at a glance what was found. Set requireEmail if you only want fully-contactable rows.

Can I search several niches at once? Yes. Add close variations to searchQueries. Each is searched separately, then merged and de-duplicated so the same advertiser is scored once.

Do I need to configure a proxy? No. The actor automatically requests a residential proxy for its Meta traffic (Meta rate-limits shared datacenter IPs aggressively) and falls back gracefully if your account does not have one. Nothing to turn on.

Is this allowed? It collects publicly visible ad and business information straight from Meta's own public Ad Library and each business's own website. You are responsible for using the data in line with applicable laws and platform terms, including marketing and anti-spam rules (e.g. CAN-SPAM, GDPR) when you run outreach.


Limitations

  • Meta's Ad Library only shows ads currently classified as active; an advertiser that paused ads the same day will not appear.
  • activeAdCount reflects ads matching your search queries, not an advertiser's full library. Use adLibraryPageUrl for the complete picture.
  • Very high-volume advertisers with many near-duplicate ads (which Meta itself groups together) may show a lower activeAdCount than their true total.
  • Video detection reads the actual creative and covers carousel and catalog video, but if Meta serves no playable asset for an ad it will be counted as non-video. The error direction is undercounting, never overcounting.
  • Contact info depends on what a business actually publishes; a real, active advertiser can still come back with no email or phone.
  • Cross-run history identifies advertisers by Facebook Page ID. The rare advertiser without one cannot be tracked, shows advertiserStatus: UNKNOWN, and is always returned rather than silently dropped.
  • advertiserStatus: NEW means new to your scans, not new to Meta. An advertiser running ads for years is still NEW the first time your search surfaces them.
  • History is per Apify account and has no expiry. It is not shared between users, and it does not carry over if you run the actor from a different account. Up to 50,000 advertisers are remembered — roughly 60 years of a weekly run — after which the least-recently-delivered are dropped first.
  • To deliberately revisit advertisers you have already received, switch historyMode to TRACK, which returns everything and labels each row NEW or RETURNING.
  • Score thresholds are currently set to sensible defaults rather than statistically calibrated ones. They rank advertisers reliably against each other; treat the absolute numbers as a priority order, not a precise measurement.
  • activeAdCount and creativeVelocity are activity signals, not ad spend. See the note above.

Contact / feedback

Bug reports, feature requests, and use-case tips are welcome. Email the developer at leafydevjr@gmail.com.