Winning Ad Creatives - Top Performing Competitor Google Ads
Pricing
from $5.00 / 1,000 results
Winning Ad Creatives - Top Performing Competitor Google Ads
Find the best performing competitor ads on Google. Ranks winning ad creatives by how long each has actually been served - the honest proxy for what works, since Google publishes no spend or impressions. Returns a scored top-N list with every input to the score, so you can audit it.
Pricing
from $5.00 / 1,000 results
Rating
0.0
(0)
Developer
mochi
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Winning Ad Creatives — Top Performing Competitor Google Ads
Find the best performing competitor ads on Google — ranked, not dumped.
Every other Google ad scraper hands you a pile of unsorted creatives and leaves you to guess which ones matter. This actor fetches a wide pool of a competitor's ads, measures how long each creative has actually been served, and returns a short ranked list of the ads that are working — with the score and every input to it, so you can check the ranking instead of trusting it.
Why longevity identifies winning ad creatives
Google's Ads Transparency Center publishes no impressions, no spend, no clicks. Nobody can scrape performance data from it, because it isn't there.
What it does publish is how long each creative has run. And advertisers behave in a very consistent way: they kill losing ads quickly and keep winners running. Nobody pays to serve the same creative for 400 days unless it earns its slot. So run-length is the best publicly available read on which of a competitor's ads are working.
That is a proxy inferred from advertiser behaviour, not a measurement of performance — see What this is not before you rely on it.
What you get
A ranked table, best-performing first:
| rank | longevityScore | advertiser | daysShown | daysRunning | dutyCycle | isActive |
|---|---|---|---|---|---|---|
| 1 | 99.7 | Booking.com | 1740 | 1739.7 | 1.0 | true |
| 2 | 92.4 | Hubspot, Inc. | 589 | 587.7 | 1.0 | true |
| 3 | 61.1 | Example Co | 73 | 365.0 | 0.2 | true |
Plus the creative itself (previewUrl, imageUrl), a deep link back to Google's own page
(adLibraryUrl), and the advertiser's identifiers.
Use cases
- Competitor ad performance analysis — see which of a rival's creatives survive, and for how long.
- Creative research before a launch — copy the angles that have been running for years, not the ones that were tested for a week and dropped.
- Top Google Ads competitor tracking — run several domains at once with
topPerAdvertiserto get each competitor's best ads side by side. - Messaging teardowns — the longest-running ad in a niche is usually its strongest offer.
How the score works
Three signals, all measured, all emitted on the row so you can recompute the score yourself.
| Signal | Field | What it means |
|---|---|---|
| Days shown | daysShown | Distinct calendar days the creative was actually served. |
| Calendar span | daysRunning | Days from firstShown to lastShown. |
| Consistency | dutyCycle | daysShown / daysRunning — the share of its lifetime the ad was actually live. |
dutyCycle is the one that does the real work. Two ads can both be "2 years old", but one ran every
single day and the other ran for six weeks and sat dormant. We measured live examples as low as
0.11 — 499 elapsed days, only 57 of them served. The first ad is a proven workhorse; the second
was tested and shelved. Longevity alone cannot tell them apart; dutyCycle can.
The formula
sustainScore = ln(1 + daysShown) / ln(1 + 1825) capped at 1.0consistencyScore = dutyCycle (falls back to sustainScore if unmeasurable)recencyScore = 1 if still running, else max(0, 1 - daysSinceLastShown / 90)longevityScore = 100 x (0.55 x sustainScore + 0.30 x consistencyScore + 0.15 x recencyScore)
Why these numbers:
- Log scale on days shown — the gap between a 3-day ad and a 90-day ad matters enormously; the gap between 1,200 and 1,300 days barely matters. A log curve keeps the score discriminating where the decisions actually are.
- 1825 days (5 years) is just beyond the oldest ad the Transparency Center can report, so the longest-lived ads approach 1.0 without a crowd of them pinning to it. (An earlier 365-day reference tied 50 of 359 test creatives at exactly 100 — the whole top of the list was arbitrary. Fixed.)
- 0.55 / 0.30 / 0.15 — staying power is the primary signal, consistency separates workhorses from shelved ads, and recency is a modest penalty so a strong-but-dead ad cannot top the list.
- 90-day decay — an ad stopped three months ago tells you about last quarter, not this one.
Don't like the weights? Every input is in the output. Sort by daysShown, dutyCycle or
daysRunning with sortBy, or re-rank the dataset yourself.
What this is not
Read this bit. It is the difference between using the actor well and being disappointed by it.
- This is not measured ad performance. No impressions, no spend, no clicks, no CTR, no ROAS.
Google does not publish them, so nobody can scrape them.
longevityScoreis an inference from how long an advertiser chose to keep serving a creative. - Long-running does not always mean high-performing. Always-on brand campaigns, evergreen remarketing, and plain neglect all produce long-lived ads. The signal is reliable in aggregate and across a competitor's whole account; treat any single row as a hypothesis, not a fact.
- Durations are a lower bound for older ads. The Transparency Center reports nothing before
2021-10-25. Ads that started earlier are reported at that floor, so their true run is longer
than shown. Those rows are flagged
isDurationCensored: true. - Most of what the source returns is currently running. Across 359 creatives captured by domain search, every single one had been shown within a day or two — so for well-known brands the ranking mostly compares how long each still-live ad has survived, which is the useful comparison anyway. Stopped ads do appear for some advertisers (we measured creatives last shown 44 and 206 days ago), and those are pushed down by the recency term. Don't expect a full graveyard of long-dead ads, though: this is not a historical archive.
- A single dominant advertiser can fill the top page with a cohort of evergreen ads that all tie
at the ceiling. Use
topPerAdvertiserto force a cross-competitor view. - Keyword mode is an advertiser autocomplete, not a keyword-bid lookup. Google's suggestion
endpoint matches advertiser names and domains, so
"asana"and"hubspot"resolve well while"project management software"returns nothing — no advertiser is called that. To analyse a category, usedomainmode with the competitor domains you care about. The run logs a warning explaining this whenever a keyword resolves to nothing.
Input
Every field has a default — running with no input at all works.
| Field | Default | What it does |
|---|---|---|
searchMode | domain | domain (brand/domain), keyword (auto-resolve advertisers), advertiser (AR… IDs). |
queries | ["nike.com"] | The competitors to analyse; must match searchMode. |
region | anywhere | Country name or code (US, United Kingdom, DE). Unknown values fall back to global. |
maxResults | 20 | How many winning ads to return. This is what you are billed for. |
maxAdsToAnalyze | 200 | Candidate pool fetched and scored before picking winners. Not billed. |
sortBy | longevity | longevity, daysShown, dutyCycle, daysRunning, recency. |
minDaysRunning | 0 | Drop ads with a shorter span. Use ~30 to skip recent tests. |
minDaysShown | 0 | Drop ads served on fewer distinct days. |
minDutyCycle | 0 | Drop inconsistent ads. 0.8 = near-continuous evergreen only. |
topPerAdvertiser | 0 | Cap each advertiser's rows so one competitor cannot fill the list. |
adFormats | [] | Keep only text / image / video. |
dateFrom / dateTo | "" | Only ads overlapping this window (YYYY-MM-DD). |
activeWithinDays | 7 | How recently an ad must have run to count as still running. |
includeUnrankable | false | Append ads that couldn't be scored, with rank/score null. |
maxAdvertisersPerKeyword | 3 | Keyword mode: how many resolved advertisers to expand. |
You pay for winners, not for the search. Fetching the candidate pool is free; only returned rows are billed. The default run scores 200 ads to give you the best 20.
Example — each competitor's 5 best ads
{"searchMode": "domain","queries": ["hubspot.com", "salesforce.com", "zoho.com"],"region": "US","maxAdsToAnalyze": 600,"maxResults": 15,"topPerAdvertiser": 5,"minDaysRunning": 60}
Example — proven evergreen creatives only
{"queries": ["booking.com"],"minDaysShown": 180,"minDutyCycle": 0.8,"sortBy": "dutyCycle","maxResults": 25}
Output fields
| Field | Description |
|---|---|
rank | 1-based position in the ranking (null if unrankable). |
longevityScore | 0–100 composite. A proxy — see What this is not. |
daysShown | Distinct calendar days the creative actually ran. |
daysRunning | Calendar span from firstShown to lastShown. |
dutyCycle | daysShown / daysRunning, 0–1. null for ads under 3 days. |
isActive | Served within activeWithinDays. |
daysSinceLastShown | Days since the creative last ran. |
isDurationCensored | true = started on/before the 2021-10-25 data floor; duration is a lower bound. |
sustainScore, consistencyScore, recencyScore | The three sub-scores, 0–1. |
daysShownEstimated | true if daysShown was absent and the span was used instead. |
rankable, excludedReason | Whether the ad could be scored, and why not. |
advertiserName, advertiserDomain, advertiserId | The advertiser (company-level). |
creativeId, adFormat | The creative and its type (text/image/video). |
firstShown, lastShown | ISO 8601 UTC. firstShownTs/lastShownTs are unix seconds. |
previewUrl, imageUrl | The rendered creative; direct image URL for image ads. |
adLibraryUrl | Deep link to Google's own page for the ad — verify any row by hand. |
analysisPoolSize, analysisCoveragePct | How many ads this row was ranked against, and what share could be scored. |
matchedQuery, searchMode, region, source, scrapedAt | Run context. |
Ads with missing or contradictory dates are excluded from the ranking rather than scored wrongly;
they carry rankable: false and an excludedReason, and are only emitted if you ask for them. The
RUN_SUMMARY key-value record reports the coverage rate and a breakdown of every exclusion, so
nothing disappears silently. Across 359 real creatives from five separate captures, timestamp
coverage measured 100% — but the handling is there because a sample is not a guarantee.
Use with AI agents (MCP)
This actor is available to any MCP-compatible AI agent (Claude, ChatGPT, Cursor, LangChain) through the
hosted Apify MCP server — no wrapper or extra setup needed. Connect once, then
ask the agent to run mochiboo/winning-ad-creatives-scraper.
Want only this actor as a tool, with no store search in the way? Point the agent at
https://mcp.apify.com/?actors=mochiboo/winning-ad-creatives-scraper and it loads as a single named tool —
the agent calls it directly instead of searching for it and possibly picking someone else.
It is built to be agent-friendly:
- Small, cheap default run (20 ranked creatives) so an agent can probe before committing budget.
- The ranking is the point for an agent — instead of handing back hundreds of raw ads for the model to reason over, it returns the few creatives that survived longest, already scored. Far less context burned per useful answer.
- Short, literal input field descriptions — an agent can fill the schema with no extra documentation.
- Flat output — one level deep, no decode logic required.
RUN_SUMMARYin the key-value store reports coverage and every exclusion, so an agent can confirm completeness without reading each row.
Related ad-intelligence actors
These pair with this actor and share the same flat schema style:
- Google Ads Transparency Scraper — the unranked firehose this one scores; use it when you want every ad, not just the winners.
- Competitor Ad Monitor — schedule it and get only the ads that changed since last run.
- Competitor Ad Intel — All Platforms — one input, Google and Bing ads back in a single normalized dataset.
- YouTube Ads Scraper — video ads only, each resolved to a real YouTube video ID, watch URL, thumbnail and duration.
- Bing Ads Library Scraper — the same idea for the Microsoft/Bing Ads Library.
Support & feedback
Something wrong, or a field you need that is not here? Open an issue on the actor's Issues tab — it is read and answered. If the actor did what you needed, a rating on the store page genuinely helps other buyers judge it.
Notes
- Data source: Google's public Ads Transparency Center. No login, no personal data.
- Company-level only. Advertisers are organisations; the output has no personal-data field to strip, which is verified by an automated test on real output rather than assumed (PDPA/GDPR-clean).
- Reproducible. The same pool ranks the same way every time; ties are broken by days shown.