Google Ads Transparency Scraper
Pricing
from $0.90 / 1,000 scraped ads
Google Ads Transparency Scraper
Search Google's Ads Transparency Center by brand, domain or advertiser ID - no advertiser URL needed. Get ad copy, landing page URLs, and how many days each ad actually served. Political ads add the disclosed spend range, impressions and targeting.
Pricing
from $0.90 / 1,000 scraped ads
Rating
0.0
(0)
Developer
Rouzbeh Vosough Ahmadi
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Google Ads Transparency Scraper — spy on competitor ads, creatives and spend
Scrape the Google Ads Transparency Center by brand name or domain — no advertiser URL to hunt down first, no login, no Google API key — and export every ad with its copy, its landing page, how long it actually ran, and, for political ads, the disclosed spend range. Results download as JSON, CSV or Excel, or come straight back over the Apify API.
Ad-spy suites charge $100–500 a month for a view of this data. This reads it from Google's own public archive and bills per ad, so a one-off competitor teardown costs cents.
What you can do with it
- Competitor teardown — every ad a rival is running, with copy and landing pages
- Find the ads that actually work —
days_servedandserving_densityseparate evergreen winners from things a brand tested for a week (no other Transparency Center actor exposes this) - Political and issue-ad monitoring — disclosed spend ranges, impressions and targeting
- Landing-page and offer tracking — where the money is actually sending traffic
- Creative libraries — image and video creative URLs for swipe files
What you get
Every row carries:
advertiser_id,advertiser_name,creative_id,ad_urlformat—image,textorvideofirst_shown,last_showndays_served— how many days the ad actually ran. Google's own page words this as "Ran for: 280 days, nonconsecutively", and it is often far below the calendar spanspan_daysandserving_density— days served divided by the span.0.99is an always-on evergreen;0.15is a short seasonal burstimage_urlfor image ads
With Extract ad copy on (the default), ads that expose text also carry:
headline,body,visible(the display URL) anddestination— the real landing pagecopy_sourceandenrich_status, so you can see where each row's copy came from and how many rows got any
With Fetch full ad detail on:
variation_count, and a per-countryregions[]breakdown with impression ranges and dates- For political and issue ads:
spend_min/spend_max(a disclosed range, in whole currency units),impressions_in_region,impressions_all_regions, andtargeting
How much copy actually comes back
Being straight about this, because it varies by ad type and it is the reason to choose this actor over a cheaper one.
Only some ads have a fetchable preview at all — image ads served as a bare creative do not. So the number that decides your result is how many of an advertiser's ads are text or search ads, and that varies enormously by advertiser. Measured on 100-ad runs:
| Advertiser | Ads | With a preview | Landing page | Headline / body |
|---|---|---|---|---|
| HubSpot | 100 | 47 | 45 | 1 |
| Squarespace | 100 | 6 | 6 | 6 |
| Nike | 100 | 5 | 1 | 1 |
The rule of thumb: once an ad has a preview, a landing page almost always comes with it; headline and body come back for text and search ads, not for display ads. Nike is the worst case worth knowing about — a brand that advertises almost entirely with images will return long-running dates and creative IDs, but very little text.
Copy is billed only when a headline or body actually arrives, so an image-heavy run does not pay for empty columns.
Why days_served is the interesting number
An ad that served 1,445 days out of a possible 1,449 is an ad that makes money — nobody keeps
paying for four years to run a loser. Set minDaysServed: 90, or minServingDensity: 0.8, and
the output stops being "every ad this brand ever tested" and becomes "the ones that worked".
Input
{"queries": ["nike.com", "shopify", "AR16735076323512287233"],"regions": ["US", "CA"],"maxAdsPerAdvertiser": 100,"maxAdvertisersPerQuery": 3,"includeAdCopy": true,"includeDetail": false,"minDaysServed": 90}
queries takes a brand name, a domain, a Google advertiser ID, or a pasted Ads Transparency
Center URL — so if you already have advertiser URLs from another tool, they work unchanged.
regions takes two-letter country codes (US, CA, GB, DE, …). Numeric Google geo-target
IDs work too.
A brand name can match several advertiser entities — "shopify.com" matches Shopify Inc. plus three unrelated advertisers with "shopify" in the name. The largest are used and the rest are named in the log, so nothing is silently dropped or silently billed.
Every option
| Option | Default | What it does |
|---|---|---|
queries | hubspot.com | Brand, domain, advertiser ID or Transparency Center URL. Omit it entirely and the run falls back to a demo query. |
regions | ["US"] | Two-letter ISO codes, or numeric Google geo-target IDs. Country names are rejected. |
maxAdsPerAdvertiser | 100 | Caps each advertiser, and therefore the cost. |
maxAdvertisersPerQuery | 1 | How many matching advertisers one query may expand to. |
includeAdCopy | true | Fetch each ad's preview for headline, body, display URL and landing page. |
includeDetail | false | Adds creative variations, per-country impressions, and political spend and targeting. One extra request per ad. |
onlyPolitical | false | Keep only ads carrying election-advertising disclosure. Implies full detail, and most commercial brands return nothing. |
minDaysServed | 0 | Drop ads that served fewer days than this. |
minServingDensity | 0 | Drop ads below this days-served ÷ span ratio. |
enrichWorkers | 8 | Parallel preview fetches. Lower it if a run starts backing off. |
proxyConfiguration | none | Optional here — the Chrome TLS fingerprint is what gets us served, not the IP. Datacenter proxies are plenty; residential costs more than the run itself. |
Output
See sample_output.json for full rows. Abridged:
{"advertiser_name": "National Democratic Redistricting Committee","headline": "A.G. Eric Holder's NDRC - End Gerrymandering","body": "Eric Holder, A.G. for President Obama, founded the NDRC to protect our democracy.","destination": "https://secure.actblue.com/","format": "image","first_shown": "2022-03-04","last_shown": "2024-01-01","days_served": 665,"span_days": 669,"serving_density": 0.994,"is_political": true,"political_confidence": "high","spend_min": { "currency": "USD", "amount": 500 },"spend_max": { "currency": "USD", "amount": 600 },"impressions_in_region": { "min": 70000, "max": 80000 }}
Watch a competitor on a schedule
Competitor monitoring is worth more as a diff than as a snapshot. Save the run as a task, give it a schedule, and each run appends to the same dataset so you can see what launched and what was retired:
- Run it once with the advertisers you care about.
- Save as a new task, then Schedule → daily or weekly.
- Point the task's Integrations at Google Sheets, Slack, a webhook or your warehouse.
A daily 100-ad watch on one advertiser costs about $3.30 a month.
Use it from your own code
curl -X POST "https://api.apify.com/v2/acts/adatlas~google-ads-transparency-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H 'content-type: application/json' \-d '{"queries":["hubspot.com"],"regions":["US"],"maxAdsPerAdvertiser":50}'
Official clients exist for Python and JavaScript, and the actor also works over MCP, so an AI agent can call it directly.
Pricing
Pay per event, so a run that finds nothing costs almost nothing:
| Event | Price | Charged |
|---|---|---|
apify-actor-start | $0.0005 | once per run, by the platform, whatever the run returns |
ad-scraped | $0.0009 | per ad delivered |
ad-copy-enriched | $0.0006 | only when headline or body text actually came back |
ad-detail-fetched | $0.0015 | only when the detail request succeeded |
A 100-ad run with copy enabled typically lands near $1.10 per 1,000 ads.
You are never charged for a column that came back empty. Image ads carry no extractable text, so on an image-heavy advertiser the copy event fires on only a few rows — and the landing page, where Google exposes one, rides along at no extra cost.
FAQ
Do I need a Google account or an API key? No. The Ads Transparency Center is a public archive; this actor uses no login and accesses nothing private.
Can I search by brand name instead of an advertiser URL? Yes — that is the main difference from most alternatives. Brand names, domains, advertiser IDs and pasted Transparency Center URLs all work.
Can I get competitor ad spend? For political and issue advertising, yes: Google discloses a spend range and this actor returns it. Commercial advertisers have no disclosed spend anywhere in the Transparency Center — any tool claiming otherwise is estimating.
Which countries are supported? 48 markets by two-letter code, plus any numeric Google geo-target ID.
How do I get only the long-running ads?
minDaysServed: 90 or minServingDensity: 0.8.
Can I export to CSV or Excel? Yes — every Apify dataset exports to JSON, CSV, Excel, XML and HTML table.
Notes and limits
- Data comes from Google's public Ads Transparency Center, an archive Google publishes to meet advertising-disclosure rules. No login is used and nothing private is accessed.
- Spend, impression and targeting figures exist only for political and issue advertising, and only in the jurisdictions where disclosure is required. Commercial ads have none of them — that is Google's disclosure boundary, not a gap in this actor.
- Impressions come in two flavours because Google reports them two ways:
impressions_in_regionmatches the number shown on the ad's own page for that country, whileimpressions_all_regionsis the global total. maxAdsPerAdvertisercaps each advertiser. Large brands have thousands of ads on file, so a run returns the cap, not the entire archive.- Ad delivery platform is reported as
platform_codewith a label only where the code has been confirmed against Google's own UI. Unconfirmed codes ship as a number rather than a guess.