Google Ads Transparency Scraper avatar

Google Ads Transparency Scraper

Pricing

from $0.90 / 1,000 scraped ads

Go to Apify Store
Google Ads Transparency Scraper

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

Rouzbeh Vosough Ahmadi

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

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 workdays_served and serving_density separate 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_url
  • formatimage, text or video
  • first_shown, last_shown
  • days_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 span
  • span_days and serving_density — days served divided by the span. 0.99 is an always-on evergreen; 0.15 is a short seasonal burst
  • image_url for image ads

With Extract ad copy on (the default), ads that expose text also carry:

  • headline, body, visible (the display URL) and destination — the real landing page
  • copy_source and enrich_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-country regions[] 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, and targeting

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:

AdvertiserAdsWith a previewLanding pageHeadline / body
HubSpot10047451
Squarespace100666
Nike100511

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

OptionDefaultWhat it does
querieshubspot.comBrand, 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.
maxAdsPerAdvertiser100Caps each advertiser, and therefore the cost.
maxAdvertisersPerQuery1How many matching advertisers one query may expand to.
includeAdCopytrueFetch each ad's preview for headline, body, display URL and landing page.
includeDetailfalseAdds creative variations, per-country impressions, and political spend and targeting. One extra request per ad.
onlyPoliticalfalseKeep only ads carrying election-advertising disclosure. Implies full detail, and most commercial brands return nothing.
minDaysServed0Drop ads that served fewer days than this.
minServingDensity0Drop ads below this days-served ÷ span ratio.
enrichWorkers8Parallel preview fetches. Lower it if a run starts backing off.
proxyConfigurationnoneOptional 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:

  1. Run it once with the advertisers you care about.
  2. Save as a new task, then Schedule → daily or weekly.
  3. 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:

EventPriceCharged
apify-actor-start$0.0005once per run, by the platform, whatever the run returns
ad-scraped$0.0009per ad delivered
ad-copy-enriched$0.0006only when headline or body text actually came back
ad-detail-fetched$0.0015only 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_region matches the number shown on the ad's own page for that country, while impressions_all_regions is the global total.
  • maxAdsPerAdvertiser caps 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_code with a label only where the code has been confirmed against Google's own UI. Unconfirmed codes ship as a number rather than a guess.