Google Ads Transparency Scraper & Ad Monitor
Pricing
from $0.80 / 1,000 ads
Google Ads Transparency Scraper & Ad Monitor
Scrape Google Ads Transparency Center ads by domain, advertiser or URL. Monitor competitors: get new, reactivated and ended ads since the last run.
Pricing
from $0.80 / 1,000 ads
Rating
0.0
(0)
Developer
Lighthouse Data
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Get every ad a company runs on Google Search, YouTube, Shopping, Maps and Play from the public Google Ads Transparency Center. Look up competitors by website domain, advertiser name, advertiser ID or pasted URL. Put the Actor on a schedule to get a change report: which ads are new, which came back, and which have ended since the last run.
No login, no cookies, no browser. You get clean JSON, CSV or Excel, and you pay only for the ads you receive.
What does Google Ads Transparency Scraper & Ad Monitor do?
- Scrapes ad creatives for any advertiser:
- advertiser name and ID, the domain the ad points to, and the format (text, image or video)
- first and last shown dates, and the number of days shown
- the creative image URL or the Google preview URL
- a deep link to the ad on adstransparency.google.com
- Monitors competitors on a schedule. Monitor mode remembers what it saw last time and returns only the changes:
new: ads that launched since the last run.reactivated: ads that had stopped running (ended) and are running again.ended: ads that stopped running.
- Adds reach data (optional).
- All creative variations (A/B versions).
- Per-country first and last shown dates.
- For ads shown in the EU: impression ranges per country and per platform, from Google's DSA disclosures.
- Accepts every input style in one run:
nike.comHelloFreshAR16735076323512287233- a Transparency Center URL copied from your browser
- Filters by region (any country), platform (Search, YouTube, Shopping, Maps, Play), format, and date range.
Why use it?
- A change report, not just a dump.
- Besides new ads, it tells you when a competitor stops an ad or brings one back, which is how you spot winning creatives and seasonal campaigns.
- Each run writes a per-competitor summary (active ads, new, ended).
- Cheap to run weekly. Watching 10 typical competitors costs about $0.10 a week: one small check per competitor plus the changes it finds.
- Fast and reliable. It talks directly to the Transparency Center's own data API over plain HTTPS: about 1,000 ads in under a minute, with automatic retries and IP rotation when Google rate-limits.
- Honest pricing. Proxy traffic and platform compute are included in the per-event price and never billed to you separately.
- Built for automation and AI agents. Every input and output field is documented, the default input costs about $0.03, and results are ready for Make, Zapier, Google Sheets, webhooks or the Apify MCP server.
Use cases
- Competitor ad monitoring. Get a weekly list of the ads your competitors launched, paused or relaunched, delivered to Slack, email or a spreadsheet.
- Creative research and swipe files. Pull a brand's image and video creatives, and sort by
daysShown: ads that run for months are the ones that work. - Agency reporting. Monitor every client's competitors under one schedule, with a separate memory per client.
- Market and media research. See which countries and Google surfaces a brand targets, and how many impressions its EU ads get.
- Sales intelligence. Check whether a prospect advertises on Google at all, and how actively.
- AI agents. Ask "What YouTube ads is Nike running in Germany?" and let your agent call this Actor through MCP.
How to use it
- Click Try for free (or Start).
- Enter one or more domains (e.g.
nike.com), advertiser names, advertiser IDs or Transparency Center URLs. - Optionally set Region, Google platform, Ad format or a date range.
- Click Start, then download the results as JSON, CSV or Excel, or read them through the API.
Scrape example
{"domains": ["nike.com"],"advertiserNames": ["HelloFresh"],"region": "US","platform": "YOUTUBE","maxAdsPerQuery": 50}
Set up a weekly competitor monitor (recommended)
-
Set Mode to
monitorand list your competitors' domains:{"mode": "monitor","domains": ["competitor-one.com", "competitor-two.com", "competitor-three.com"],"region": "US","includeEndedAds": true,"monitorStoreName": "acme-competitor-ads"} -
Click Save as a new task, then open the task's Schedules tab and add a schedule, e.g. every Monday at 07:00 (cron
0 7 * * 1). -
Add an integration to the task, for example Slack, email, Google Sheets or a webhook, so each week's changes reach you automatically.
- The first run saves the current ads as the
baseline(up tomaxAdsPerQueryare returned and all of them are remembered). - Every later run returns only
new,reactivatedandendedads. - Separate memories: use a different Monitor memory name per client or project.
Input
| Field | Type | Description | Example |
|---|---|---|---|
mode | string | scrape (all matching ads) or monitor (only changes since the last run) | "monitor" |
domains | string[] | Advertiser website domains. Ads from every advertiser account pointing to the domain. An input with no lookups at all runs the example nike.com | ["nike.com"] |
advertiserNames | string[] | Brand or company names, resolved to the verified advertiser account(s) with the most ads | ["HelloFresh"] |
advertiserIds | string[] | Google advertiser IDs (AR + 20 digits) | ["AR16735076323512287233"] |
startUrls | URL[] | Transparency Center advertiser, creative or domain URLs | [{"url": "https://adstransparency.google.com/advertiser/AR16735076323512287233"}] |
region | string | ISO country code or anywhere | "DE" |
platform | string | ALL, SEARCH, YOUTUBE, SHOPPING, MAPS, PLAY | "YOUTUBE" |
format | string | ALL, TEXT, IMAGE, VIDEO | "VIDEO" |
dateFrom / dateTo | string | Only ads shown within this window (YYYY-MM-DD, last ~12 months; scrape mode only) | "2026-06-01" |
maxAdsPerQuery | integer | Max records per domain/advertiser/URL (default 20; 0 = no limit). Caps your cost | 100 |
maxAdvertisersPerName | integer | Advertiser accounts to use per name, biggest first | 3 |
includeDetails | boolean | Add variations, per-country dates and EU impressions (extra event) | true |
monitorStoreName | string | Named key-value store that holds the monitor memory | "acme-competitor-ads" |
includeEndedAds | boolean | Monitor mode: also return ads that stopped running | true |
endedAfterDays | integer | An ad counts as ended after this many days without being shown | 3 |
baselineLookbackDays | integer | First monitor run: ads shown within this many days form the baseline | 30 |
maxScanPerQuery | integer | Monitor mode: cap on live ads read per query and run (one monitor check per started 1,000) | 3000 |
proxyConfiguration | object | Proxy settings. Residential is the default and recommended | {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]} |
Output
See real output: 20 records from a real run (JSON). This is the built-in example (empty input), run on 2026-10-06 with build 0.1.9.
Each dataset item is one ad. This is a real record for nike.com:
{"creativeId": "CR18136630512767205377","advertiserId": "AR18378488041124659201","advertiserName": "Nike Retail BV","domain": "nike.com","format": "TEXT","firstShownAt": "2025-09-19T13:06:18.353Z","lastShownAt": "2026-09-29T21:26:59.590Z","daysShown": 321,"imageUrl": "https://tpc.googlesyndication.com/archive/simgad/4610137042240554284","imageWidth": 348,"imageHeight": 421,"previewUrl": null,"adUrl": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR18136630512767205377","queryType": "domain","queryValue": "nike.com","regionFilter": null,"platformFilter": null,"changeType": null,"variationCount": null,"variations": null,"regions": null,"impressionsMin": null,"impressionsMax": null,"url": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR18136630512767205377","scrapedAt": "2026-09-29T21:58:29.447Z","isComplete": true}
With Include ad details on, the detail fields are filled. This excerpt is from a real EU video ad:
{"variationCount": 5,"regions": [{"regionCode": "ES","regionName": "Spain","firstShownDate": "2025-09-15","lastShownDate": "2026-09-29","impressionsMin": 10000000,"impressionsMax": null,"platforms": [{ "platform": "MAPS", "impressionsMin": 10000000, "impressionsMax": null },{ "platform": "YOUTUBE", "impressionsMin": 10000000, "impressionsMax": null },{ "platform": "SEARCH", "impressionsMin": 175000, "impressionsMax": 200000 }]}],"impressionsMin": 10000000,"impressionsMax": null}
Field notes:
- In monitor mode,
changeTypeisbaseline,new,reactivatedorended. endedrecords carry the ad's IDs, advertiser, format and dates. Google no longer serves their creative, so the image fields arenull.- Impression ranges are published by Google only for ads shown in the EU.
impressionsMax: nullwith aimpressionsMinmeans "at least". Missing values arenull, never guessed. isCompleteisfalsewhen Google's data for the ad lacked a core field (creative ID, advertiser or format). Such ads are saved but not charged (see Pricing).- The SUMMARY record in the run's key-value store has:
completeness: how many targets (domains, advertiser names, advertiser IDs) you asked for, and how many were delivered complete, incomplete or failed, e.g.{ "unit": "targets", "requested": 3, "delivered": 2, "incomplete": 0, "failed": 1, "ratio": 0.67 }queries: per target, itsoutcome(complete,incompleteorfailed), the resolved advertisers and Google's total-ads range, counts of ads scanned, returned, new, reactivated and ended, the active ads in memory, and any warning
- FAILED_INPUT: when any target failed or is incomplete, the key-value store also gets a
FAILED_INPUTrecord. It is your input with every setting kept and only those targets left. Paste it into a new run to retry just them.- Failed: Google did not answer after all retries, or the run reached your maximum cost per run before the target was fully read.
- Incomplete: an ad was saved with
isComplete: false, or its details could not be loaded. - Not a failure: a domain or advertiser with no ads, or an advertiser name with no verified match. Google gives the same empty answer for a domain that does not exist, so these are real answers.
- Rerunning a target cut short by the cost limit reads it from the start, so its ads are delivered (and charged) again.
The dataset has three views: Ads, Monitor changes, and Reach and impressions.
Pricing
This Actor uses pay-per-event pricing. You pay for what you get; platform compute and proxy traffic are included.
Prices by Apify plan (discount tiers):
| Event | When it is charged | Free | Bronze | Silver | Gold | Platinum | Diamond |
|---|---|---|---|---|---|---|---|
| Run start | Once per run (free when every target fails) | $0.005 | $0.005 | $0.005 | $0.005 | $0.005 | $0.005 |
| Ad | Each ad saved (scrape mode: every ad; monitor mode: baseline, new and reactivated ads) | $0.0012 | $0.0010 | $0.0009 | $0.0008 | $0.0008 | $0.0008 |
| Ad details | Each ad, only when Include ad details is on | $0.002 | $0.0018 | $0.0015 | $0.0012 | $0.0012 | $0.0012 |
| Monitor check | Monitor mode: per query and run, for each started 1,000 live ads read to find the changes | $0.008 | $0.008 | $0.008 | $0.008 | $0.008 | $0.008 |
| Ended ad | Each ended record in monitor mode | $0.0005 | $0.0004 | $0.0003 | $0.0003 | $0.0003 | $0.0003 |
Why a monitor check?
- To tell you which ads are new and which ended, the monitor reads every ad a competitor is currently running, not just the ones it returns.
- For a typical competitor with fewer than 1,000 live ads, that is one check per run.
Cost examples (Free plan prices):
- Default input (20 ads for
nike.com): $0.005 + 20 × $0.0012 = $0.029. - 1,000 ads from one advertiser: $1.205.
- 1,000 ads with details: $3.205.
- Weekly monitor of 10 competitors (each under 1,000 live ads) finding 15 new, 2 reactivated and 5 ended ads:
- $0.005 + 10 × $0.008 + 17 × $0.0012 + 5 × $0.0005 = $0.11 per run
- about $0.47 a month
- A quiet week for the same 10 competitors: $0.005 + 10 × $0.008 = $0.085.
- One big brand with 2,500 live ads: 3 checks = $0.024 per run, plus its changes.
What counts as complete (you never pay for incomplete data):
- An ad is charged only when its creative ID, advertiser (ID and name) and format were read. Otherwise it is saved with
isComplete: falseand is free. This applies toadandended-adrecords alike. - Ad details are charged only for ads whose details actually loaded. If the detail lookup fails, the ad is still delivered (and charged as an ad), the detail fields are
nulland its target is listed inFAILED_INPUT. - A monitor check is charged only after the scan of that query succeeded. A scan that fails or is cut short by your cost limit is free.
- Run start is charged only when the run delivers something: an ad, or a target Google answered (including "no ads"). A run in which every target fails costs nothing.
Staying in control of spend:
- Set Maximum cost per run in the run options. The Actor stops cleanly at that limit and never fetches data it cannot charge for.
maxAdsPerQuerycaps the records per query.maxScanPerQuerycaps the monitor checks per query.
Ready-made tasks
One-click examples with the input already filled in. Open one, adjust it and run:
- Competitor Google Search text ads
- Find a brand's YouTube video ads in the US
- Find all Google ads of an advertiser by name
- Google Shopping ads of a retailer
- Monitor a competitor's Google ads daily (new and ended)
- See all Google ads a competitor is running
- UK Google ads of a competitor (Ads Transparency, region GB)
Use it from an AI agent (MCP)
AI agents can run this Actor through Apify's MCP server. Add this server to Claude, Cursor, VS Code or any MCP client:
{"mcpServers": {"apify": { "url": "https://mcp.apify.com?tools=cylindrical_lighthouse/google-ads-transparency" }}}
You sign in to Apify in the browser on first use, or you can send the header Authorization: Bearer <APIFY_TOKEN>. VS Code's mcp.json names the top-level key servers instead of mcpServers. With the Apify CLI you can also run apify mcp install cursor (other clients are supported). Then just ask, for example: "List the Google ads hubspot.com is running and which formats they use".
Integrations
- Make, Zapier and n8n: use the Apify app or node, choose Run an Actor and pick
cylindrical_lighthouse/google-ads-transparency, then send the dataset to Google Sheets, Airtable, Slack or a database. - Google Drive and webhooks: in the Actor's Integrations tab, upload each run's results to a Drive folder or call your own URL when a run finishes.
- Schedules: in Apify Console, go to Schedules, then Create new, and pick this Actor or one of its saved tasks to research competitor ads automatically.
- API:
POST https://api.apify.com/v2/acts/cylindrical_lighthouse~google-ads-transparency/run-sync-get-dataset-items?token=<APIFY_TOKEN>runs it and returns the results in one call.
Related Actors
From the same publisher:
- Google Trends Scraper
- App Store & Google Play Reviews Scraper
- Amazon Product Scraper & Price Tracker
FAQ
Is it legal to scrape the Google Ads Transparency Center?
- Google publishes the Ads Transparency Center so that anyone can see who advertises and what they show. In the EU it is the ad repository required by the Digital Services Act.
- This Actor reads only that public data. It never logs in, uses no cookies and solves no CAPTCHAs.
- Google's Terms of Service restrict automated access to its services, so review your own use case.
- Results can contain personal data: some verified advertisers are individuals (for example sole traders or political candidates), and their names are published by Google. Personal data is protected by GDPR and other regulations. Do not process it unless you have a legitimate reason. If you are unsure, consult your lawyers.
Is this an official Google product? No. This Actor is independent and is not affiliated with, endorsed by or sponsored by Google LLC. "Google" and "Google Ads" are trademarks of Google LLC, used here only to describe the public data source.
How does monitor mode decide what is "new" or "ended"?
- New: an ad first shown after you started monitoring the query.
- Reactivated: an ad the monitor saw end that is running again.
- Missed earlier? Google reorders ads while they are being read, and very large advertisers can exceed the scan cap. An older ad that was running all along but missed by an earlier check is added to the memory silently, not reported as a change. The SUMMARY counts these as
absorbed. - Ended: an ad from the memory that Google has not shown for
endedAfterDaysdays (default 3). - Each change is reported exactly once. If a run hits
maxAdsPerQueryor your cost limit, the remaining changes are reported next time.
Where is the monitor memory stored? Can I reset it?
- It lives in the named key-value store set in Monitor memory name, in your own Apify account, with one record per query and filter combination.
- To start over, delete that store or use a new name.
- Changing the region, platform or format of a query starts a new memory for it.
Why is there no ad text for text ads?
Google archives most search text ads as images, so the headline and description are in imageUrl, not in a text field. Video and rich ads come with a Google previewUrl.
Why do I get fewer ads than Google's total?
maxAdsPerQuerylimits each query (default 20). Set it higher, or to0for everything.- Region, platform, format and date filters narrow the results, like on the website.
Can I use my own proxies? Yes, set them in Proxy configuration. Residential proxies work best, because Google rate-limits datacenter IPs quickly. The Actor retries on a new IP automatically.
Limitations
- Dates: the date filter covers roughly the last 12 months only. Google does not serve older windows, so older start dates are moved forward with a warning.
- Ad copy: text-ad copy comes as an image, not as text (see FAQ). There is no ad spend, except that EU ads carry impression ranges.
- Platform data: Google reports platform (Search, YouTube and so on) only for ads shown since September 2023.
- Advertiser names: a name resolves to verified advertiser accounts only. Very generic names may pick the wrong account; use a domain or advertiser ID to be exact.
- Monitor scan cap: monitor mode reads up to
maxScanPerQuerylive ads per query per run (default 3,000, i.e. at most 3 monitor checks). If a giant advertiser exceeds it, ended-ad detection is skipped for that run and the log says so. Monitoring a very large brand reads thousands of ads, which takes a few minutes. - Data freshness: the data is exactly what Google publishes, including its approximate ad-count and impression ranges.
Changelog
See the ./CHANGELOG.md (also on the Changelog tab).
Support
Found a bug, or need a field or filter? Open an issue on the Issues tab. We respond within 48 hours. Feature requests are welcome.
Did this Actor save you time? A short review on the Store helps other people find it and tells us what to improve. If something didn't work, please open an issue first, so we can fix it for you.