Google Ads Transparency Scraper & Competitor Monitor avatar

Google Ads Transparency Scraper & Competitor Monitor

Pricing

from $0.90 / 1,000 ad results

Go to Apify Store
Google Ads Transparency Scraper & Competitor Monitor

Google Ads Transparency Scraper & Competitor Monitor

Scrape Google ads (Search, YouTube, Shopping, Maps, Play) for any advertiser or domain from the Ads Transparency Center. Monitor competitors for new, stopped and new-country ads with Slack/webhook alerts, or bulk-check which domains advertise.

Pricing

from $0.90 / 1,000 ad results

Rating

0.0

(0)

Developer

Carina Hatton

Carina Hatton

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Security

Limited permissions

Share

Google Ads Transparency Scraper & Monitor

See the ads any company runs on Google Search, YouTube, Shopping, Maps and Play, straight from the public Google Ads Transparency Center. Export a competitor's ads to a spreadsheet, get alerted when a rival launches or stops an ad, or check a list of domains to see who advertises on Google.

Enter an advertiser name, a domain, an advertiser ID or any Transparency Center URL. You get structured data: ad text where Google publishes it, image URLs, YouTube video IDs, first and last shown dates, formats and a direct link to every ad.

Built for agencies and competitor-research teams

  • Competitor ad research: every creative a competitor is running right now, and since when.
  • Competitor alerts: schedule the monitor and get a Slack message or webhook when a rival launches new ads, stops ads or enters a new country.
  • Agency pitches and audits: export a prospect's ad history before the first call.
  • Lead qualification: check a list of domains to see which companies advertise on Google, and roughly how much.
  • Creative inspiration: collect headlines, descriptions and YouTube videos from your category.

Three modes

ModeWhat it doesTypical use
Scrape adsLists ads for each advertiser or domain, newest first, with optional per-ad detailsOne-off research and exports
Monitor for changesCompares the latest ads with the previous run and reports NEW_AD, AD_STOPPED, AD_RESUMED and NEW_REGIONScheduled daily or weekly competitor tracking
Batch domain checkOne quick lookup per domain: is it advertising on Google, roughly how many ads does Google say it has, and when was its latest ad shownQualifying lead lists

Quick start

Scrape a competitor's ads

{
"mode": "scrape",
"targets": ["nike.com"],
"regions": ["US"],
"maxResultsPerTarget": 100
}

Each ad becomes one row in the dataset. Turn on "fetchDetails": true for all variations and per-region dates (charged per ad, see Pricing).

Monitor competitors for changes

{
"mode": "monitor",
"targets": ["AR16735076323512287233", "hubspot.com"],
"regions": ["US"],
"monitorStoreName": "my-competitors",
"slackWebhookUrl": "https://hooks.slack.com/services/…"
}

Save it as a Task and schedule it, for example daily. The first run records a baseline; later runs report only what changed.

Check which domains advertise

{
"mode": "domainCheck",
"targets": ["nike.com", "hubspot.com", "shopify.com"],
"regions": ["US"]
}

One row per domain and region: is it advertising now, Google's estimated ad count, its latest ad date and the advertiser accounts behind it.

Input

FieldNotes
Advertisers, domains or URLsOne per line. The type is detected automatically:
• AR… advertiser ID
• nike.com domain
• HubSpot name, looked up with Google's own search suggestions
• any adstransparency.google.com URL, including single-ad URLs. Filters in the URL (region, platform, format, dates) are respected.
RegionsOne or more countries, or "Anywhere".
PlatformsSearch, YouTube, Shopping, Maps, Play. Leave empty for all platforms.
Ad formatsText, Image, Video. Leave empty for all formats.
Shown from / untilDate range.
Max ads per target / in totalStrict caps. The run stops when it reaches them.
Fetch ad detailsAdds all variations and per-region dates. For EU regions it also adds the impression ranges Google publishes, by platform. Costs one extra request per ad.
ProxyResidential proxy is the default and is strongly recommended.

Example with a URL and filters:

{
"mode": "scrape",
"targets": ["hubspot.com", "https://adstransparency.google.com/advertiser/AR16735076323512287233?region=US&platform=YOUTUBE"],
"regions": ["US"],
"formats": ["VIDEO"],
"maxResultsPerTarget": 50
}

Output

Each ad is one dataset item. Below is a real item from a test run on 30 Oct 2026, shortened:

{
"type": "ad",
"advertiserId": "AR10072600183532683265",
"advertiserName": "Hubspot, Inc.",
"creativeId": "CR15036202842803142657",
"format": "VIDEO",
"platforms": ["YOUTUBE"],
"platformsSource": "platform-filter",
"firstShown": "…",
"lastShown": "2026-10-30T…Z",
"matchedRegions": ["US"],
"youtubeVideoId": "kJ26TwqroAk",
"youtubeUrl": "https://www.youtube.com/watch?v=kJ26TwqroAk",
"adCopy": {
"headline": "Know your customers. Close more deals.",
"longHeadline": "Everything your team needs to grow. Get started free with HubSpot Smart CRM.",
"description": "Track every contact, call, and deal in one place so nothing slips through the cracks.",
"callToAction": "Sign up",
"source": "preview-js"
},
"detailsFetched": true,
"regions": [{ "regionCode": "US", "lastShown": "2026-10-30" }, { "regionCode": "CA", "lastShown": "…" }],
"variations": [ … ],
"adUrl": "https://adstransparency.google.com/advertiser/AR10072600183532683265/creative/CR15036202842803142657?region=US"
}

Key fields:

  • format: TEXT, IMAGE or VIDEO. This is the label Google itself shows on the ad's page. It was checked against the live site.
  • adCopy: headline, description, display URL and call to action. adCopy.source says how the text was obtained:
    • overlay: decoded from Google's own preview data.
    • overlay-extra-texts: a best guess when Google gives text without labels, for example local/Maps ads.
    • preview-js: video and display ads.
    • preview-shopping: Shopping product title and merchant.
  • imageUrl: the ad image. Many text ads are published by Google only as an image. For those, renderedAsImage is true and adCopy is null, because the text exists only inside the picture.
  • platforms: which Google platforms the ad matched. Google's ad list does not include this, so it is filled only in two cases:
    • when you filter by platform (platformsSource: "platform-filter")
    • from EU impression data when details are fetched
  • regions (with details):
    • for every region: last shown date
    • for EU regions only: first shown date and impression ranges per platform. This is all Google publishes.
  • adUrl / advertiserUrl: links to the Transparency Center.

Monitor mode writes monitorEvent items (event: NEW_AD, AD_STOPPED, AD_RESUMED, NEW_REGION).

Domain check writes domainCheck items. A real item from a test run on 30 Oct 2026:

{
"type": "domainCheck",
"domain": "nike.com",
"region": "US",
"isAdvertising": true,
"hasAdHistory": true,
"googleEstimatedAdsMin": 8000,
"googleEstimatedAdsMax": 9000,
"latestAdLastShown": "2026-10-30T23:56:08.000Z",
"advertisers": [
{ "advertiserId": "AR16735076323512287233", "advertiserName": "Nike, Inc." },
{ "advertiserId": "AR06365026152670560257", "advertiserName": "WPP MEDIA MANAGEMENT" },
{ "advertiserId": "AR18378488041124659201", "advertiserName": "Nike Retail BV" }
],
"transparencyUrl": "https://adstransparency.google.com/?region=US&domain=nike.com",
"status": "OK"
}

Monitor events carry the same ad fields plus event, monitoredTarget and detectedAt. The dataset has a separate table view for each item type.

Honest run status

Every run saves a RUN_SUMMARY record in its key-value store. For each target it compares Google's own estimated ad count with the number of ads actually returned. The run's status message calls out problems:

  • BLOCKED: Google kept refusing requests after all retries, so no ads were collected. A run where every target is blocked fails instead of returning an empty "success".
  • PARTIAL_BLOCKED: some ads were collected before Google blocked the run.
  • EMPTY_BUT_ADS_EXPECTED: Google says ads exist but returned none.
  • FEWER_THAN_ESTIMATED: Google's list ended early compared with its own estimate.
  • NO_ADS: Google has no ads for this target and filters.

You are charged only for ads and checks that were actually returned. Blocked or failed lookups are never charged; only the $0.001 run start applies.

Monitoring competitors

  1. Set Mode to Monitor for changes and add the competitors.
  2. Optional: add a Slack incoming webhook URL and/or a Webhook URL. The webhook gets a JSON POST with all events, so it works with Zapier, Make, n8n or your own endpoint.
  3. Save the input as a Task and add a Schedule, for example daily.
  4. The first run saves a baseline and reports nothing by default. Every later run reports only what changed.

What each event means:

  • NEW_AD: a creative that was not seen in earlier runs.
  • AD_STOPPED: Google's "last shown" date is older than the stopped after setting (default 3 days). An ad that disappears from the list is also flagged, but only when the list is known to cover it.
  • AD_RESUMED: a stopped ad was shown again.
  • NEW_REGION: the ad matched a region that was not seen before. Compare several regions, or turn on details, to use this.

Monitor state is kept in a named key-value store (gads-transparency-monitor by default) under your account. Use a different store name for each independent monitoring job.

Email alerts: in the Actor's or task's Integrations tab, add an email notification for successful runs. Or send the webhook to Zapier or Make and email from there.

Limits you should know

  • Many text ads are image-only. Google often publishes Search text ads only as a rendered picture, so adCopy is null and the text is only in imageUrl. In a 100-ad test of one large US advertiser on 30 Oct 2026, 98 ads were image-only text ads. Video and Shopping ads in our tests did include text.
  • Use residential proxy. Google rate-limits the Transparency Center. The Actor rotates IPs and backs off automatically, but datacenter IPs are blocked much more often.
  • Name lookups pick the best-matching advertiser account by default. Some brands have several accounts, for example a US entity and an EU entity. Raise Advertisers per name search, or use the exact AR… ID.
  • Domain searches return every ad Google links to that domain. This can include resellers or partners that advertise the domain, so check advertiserName.
  • Impressions and first-shown dates per region exist only for EU countries. Google does not publish them elsewhere.
  • Audience targeting (audienceSelectionRaw) is returned as Google publishes it, without interpretation.
  • Some ads Google labels as Video are local/Maps ads with no YouTube video. Those have youtubeVideoId: null.
  • Results are sorted the way Google sorts them: most recently shown first.

Pricing

Pay per event. You pay only for what the Actor does; platform usage (compute, proxy) is included in the price.

EventWhat triggers itPrice
Actor startOnce per run (charged automatically by Apify; once per GB of memory above 1 GB)$0.001
ad-resultEach ad returned in scrape mode$0.0018 Free, $0.0015 Bronze, $0.0012 Silver, $0.0009 Gold and above (by Apify plan tier)
ad-detailEach ad's details, when Fetch ad details is on$0.003
advertiser-checkedEach advertiser or domain checked in monitor mode$0.003
new-ad-alertEach new ad found in monitor mode$0.003
domain-checkEach domain and region checked in domain-check mode$0.003
Stopped, resumed and new-region alertsMonitor mode change eventsFree
Blocked or failed lookupsNothing returnedFree

Example: scraping 100 ads on the Apify Free plan costs $0.001 + 100 × $0.0018 = $0.181. A daily monitor of one advertiser with no new ads costs $0.001 + $0.003 = $0.004 per run.

Set a maximum cost per run in the run options. The Actor stops cleanly when it reaches it.

FAQ

What happens if Google blocks the run or returns nothing? The Actor retries with new IPs and backs off. If every target stays blocked, the run fails with a clear message instead of reporting an empty success. If Google says ads exist but returns none, the target is marked EMPTY_BUT_ADS_EXPECTED. Details for every target are in RUN_SUMMARY.

Am I charged for blocked targets or empty results? No. Ads, checks and alerts are charged only when a result is saved to your dataset. A blocked monitor target is not charged and its saved state is left unchanged. The $0.001 run start is the only fixed charge.

Are my limits respected? Yes. Max ads per target and Max ads in total are hard caps, and the Actor stops cleanly at your maximum cost per run.

Do I get the ad text, or just links? You get the text wherever Google publishes it: headline, long headline, description, call to action, and Shopping product titles. For Search text ads that Google publishes only as an image, you get the image URL (see Limits).

Why does a domain search show advertisers I don't recognise? Google lists every advertiser whose ads point to that domain, including resellers, agencies and partners. Filter by advertiserName or advertiserId.

Can I get impressions or spend? Google publishes impression ranges and first-shown dates per country only for EU regions. Turn on Fetch ad details and pick an EU region. Spend is not published.

Will the monitor spam me with old ads? No. The first run only records a baseline. After that, an ad is reported as new only when it first appeared since the previous run, not when an old ad moves back into view.

The Actor reads only the public Google Ads Transparency Center. Google publishes this site so anyone can see who is advertising and what they show. No login is needed. It collects no personal data beyond what advertisers publish. Check your local laws and Google's terms for your use case.