Google Ads Transparency Scraper & Ad Library API
Pricing
from $1.19 / 1,000 ads
Google Ads Transparency Scraper & Ad Library API
Get every ad a competitor runs from the Google Ads Transparency Center: pass one or a list of domains, advertiser IDs or brand names and get format, first and last shown, days live, countries, platforms and EU impressions. Monitor new creatives since the last run. $1.49 per 1,000 ads.
Pricing
from $1.19 / 1,000 ads
Rating
0.0
(0)
Developer
Raffy
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
11 days ago
Last modified
Categories
Security
Limited permissionsShare
What does Google Ads Transparency do?
See every ad a competitor is running right now. Type nike.com and get one row per creative — search text ads, display banners and video — with the countries each ad ran in, the day it started, the day it was last seen and how many days it has been live. Performance marketers use it for competitive ad research, creative strategists use it to find the ads a brand keeps paying for, and compliance teams use it to check what an advertiser is actually claiming in market.
The Actor reads the public Google Ads Transparency Center and turns it into clean JSON, CSV or Excel. It works as a Google Ads Transparency Center API alternative and Google Ads Library scraper: give it a brand name, a website domain, an advertiser id or an advertiser page URL and get results in seconds — no browser, no residential proxies, no scraper to maintain.
✨ Try it: press Start with the prefilled domains. Twenty ads land in about five seconds.
🔎 Search by name or website, not just by id. Most tools want an advertiser id. This one takes a brand name such as HubSpot (matched through the Transparency Center's own search box) or a plain domain, and returns the ads of every advertiser account that verified that website — brand accounts, regional entities and agencies alike.
🎛️ Filter like the website does. Narrow by country, by platform (Google Search, YouTube, Google Play, Maps, Shopping), by format and by the dates an ad was shown.
🔔 New creatives since the last run. Turn on onlyNewAds and schedule the Actor: each run returns only the creatives that were not in an earlier run, and you pay only for those.
📋 A whole competitor list in one call. Pass domains (["hubspot.com", "salesforce.com"]) or advertiserIds (["AR10072600183532683265"]) as JSON arrays, and set maxAdsPerAdvertiser so every advertiser gets its share of maxItems.
Use with AI agents
- Actor:
glasswing/google-ads-transparency-scraper - Markdown page:
https://apify.com/glasswing/google-ads-transparency-scraper.md - MCP server:
https://mcp.apify.com/?tools=glasswing/google-ads-transparency-scraper - Minimal input:
{"domains": ["nike.com"], "maxItems": 20}
For LinkedIn ads of the same companies, use the sister Actor LinkedIn Ad Library Scraper: same batch and monitor inputs.
Use cases: competitive ad research, creative inspiration, advertiser verification
- 🎯 Performance marketers doing competitive ad research. Pull every live creative of five competitors before a campaign kickoff and see which offers they keep running, which they dropped, and which countries they are pushing hardest.
- 💡 Creative strategists looking for inspiration that works. Collect image and video creatives across a category and sort by
daysShown: the ads an advertiser has been paying for the longest are the ads that survived their own testing. - ✅ Brand, legal and compliance teams verifying an advertiser's claims. Check what a partner, reseller or affiliate is really saying in paid search, in which markets, and since when — with a public source URL you can cite in the ticket.
- 📅 Agencies monitoring clients and prospects. Schedule a daily run with
onlyNewAdson and get just the new creatives of every client or competitor, ready for a Slack alert. The same data makes a persuasive new-business pitch deck. - 📺 Channel planners comparing platforms. Use the
platformfilter to see which competitors advertise on YouTube or Google Maps, and the EU impression ranges to see where they spend the most. - 🔬 Researchers, analysts and journalists building ad datasets. Assemble a longitudinal record of advertiser activity per country for market analysis, ad-tech research or brand-safety work.
- 🛒 E-commerce and affiliate teams sizing a niche. Count how many advertisers and creatives are live around a product category and how long the average creative survives, before committing budget.
The Actor does not log in, does not defeat access controls and does not collect private user data. It reads only what the Ads Transparency Center publishes to everyone.
What data you get
One row per ad (per creative). Fields are omitted when the source does not publish them; a missing field is honest, never a guess.
Who advertised
| Field | Type | What it tells you |
|---|---|---|
advertiserName | string | Verified business name of the advertiser, e.g. Nike Retail BV. Removed when the name looks like a private person rather than a business. |
advertiserDomain | string | Website the advertiser verified, e.g. nike.com. Filled when you search by domain. |
advertiserId | string | Advertiser account id, e.g. AR18378488041124659201. Stable, and usable as input for a follow-up run. Removed together with a redacted name. |
advertiserNameRedacted | boolean | true when the advertiser name looked like a private person (no legal form such as Inc or GmbH, not a website name, and not the name of the domain you typed in startUrls; a keyword match alone never keeps a name). The ad is still returned, but advertiserName and advertiserId are removed and url points to the search page. |
The ad and its flight
| Field | Type | What it tells you |
|---|---|---|
adFormat | string | text (search and text ads), image (uploaded display banners), video, or unknown. |
firstShown | string | ISO 8601 date-time the ad was first recorded as shown. |
lastShown | string | ISO 8601 date-time the ad was last recorded as shown. |
daysShown | integer | How many days the ad was recorded as running. A high number with a recent lastShown marks an evergreen winner. |
regions | array | ISO 3166-1 alpha-2 codes of every country the ad ran in, e.g. ["BE","DE","ES","FR","IT"]. |
regionCount | integer | How many country entries the source published for this ad. |
platforms | array | Google platforms the ad was recorded on: search, youtube, play, maps, shopping. Google publishes this with its EU/EEA data, so it is missing for ads that never ran in the EU. |
impressionsMin / impressionsMax | integer | Range of how often the ad was shown, as Google publishes it for EU/EEA countries. impressionsMax is absent for an open-ended range. |
impressionsByRegion | array | Per-country impression range with that country's first and last shown dates, e.g. {"region": "DE", "impressionsMin": 1000, "impressionsMax": 2000, ...}. |
targeting | object | Which audience-selection categories the advertiser used (demographics, locations, contextualSignals, topicsOfInterest, customerLists), each included, excluded, included_and_excluded or not_used. |
adId | string | Creative id of this ad, e.g. CR09696740594663030785. Unique per advertiser. |
Creative and run metadata
| Field | Type | What it tells you |
|---|---|---|
previewUrl | string | Google-hosted rendered preview of the creative — open it in a browser to see the ad. |
imageUrl | string | Direct URL of the creative image, when the source publishes one instead of a rendered preview. |
searchRegion | string | Region the search was scoped to: anywhere or an alpha-2 code. |
searchTerm | string | The input entry (domain, advertiser id, URL or keyword) this ad was found through — handy when you pass 50 domains in one run. |
searchType | string | domain, advertiser or query (found through a keyword in searchQueries). |
searchQuery | string | The keyword that matched this advertiser. Only on keyword searches. |
isNew | boolean | true on every row of an onlyNewAds run: the ad was not returned by an earlier monitor run. |
url | string | Public Ads Transparency Center page of this ad. |
status | string | ok, not_found or error (see below). |
error | string | Reason when status is not ok. |
scrapedAt | string | ISO 8601 time of extraction. |
The Ads Transparency Center publishes creatives as rendered previews, so ads carry previewUrl and/or imageUrl rather than raw headline text. Video ads are published as a preview you can open. The Actor never renders JavaScript, so it does not invent creative copy the source does not publish.
Result status (tri-state output)
status | Meaning | Billed? |
|---|---|---|
ok | The ad was found and extracted. | Yes |
not_found | The source answered, but this advertiser publishes no ads for the chosen region and format. | No |
error | The source could not be read after retries (rate limiting, network error, or a change in the endpoint). error says why. | No |
Output
Export the dataset as JSON, HTML, CSV or Excel, or read it from the API. Real rows from a run with the default input:
[{"url": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR09696740594663030785?region=anywhere","status": "ok","scrapedAt": "2026-09-08T11:50:13.816Z","advertiserId": "AR18378488041124659201","advertiserName": "Nike Retail BV","advertiserDomain": "nike.com","adId": "CR09696740594663030785","adFormat": "text","firstShown": "2026-07-21T12:24:03.000Z","lastShown": "2026-09-08T11:26:19.000Z","daysShown": 50,"imageUrl": "https://tpc.googlesyndication.com/archive/simgad/9612903277308998192","searchRegion": "anywhere","searchTerm": "nike.com","regions": ["BE", "DE", "ES", "FR", "GP", "GR", "IT", "LU", "MQ", "PT", "RE"],"regionCount": 11},{"url": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR15825683433138421761?region=anywhere","status": "ok","scrapedAt": "2026-09-08T11:50:13.816Z","advertiserId": "AR18378488041124659201","advertiserName": "Nike Retail BV","advertiserDomain": "nike.com","adId": "CR15825683433138421761","adFormat": "text","firstShown": "2025-10-22T17:43:25.000Z","lastShown": "2026-09-08T11:24:36.000Z","daysShown": 139,"imageUrl": "https://tpc.googlesyndication.com/archive/simgad/8552597266371592728","searchRegion": "anywhere","searchTerm": "nike.com","regions": ["DE", "FR", "NL"],"regionCount": 3},{"url": "https://adstransparency.google.com/?region=anywhere&domain=example-with-no-ads.com","status": "not_found","error": "No ads published for \"example-with-no-ads.com\" in region anywhere","scrapedAt": "2026-09-08T11:50:14.002Z"}]
Rows also carry searchType, and, with Include ad details on (the default), platforms, impressionsMin, impressionsMax, impressionsByRegion and targeting whenever Google publishes them.
The Ads overview dataset view shows advertiserName, advertiserDomain, adFormat, firstShown, lastShown, daysShown, regions, platforms, url, status and error. The All columns view adds advertiserId, adId, regionCount, the impression and targeting fields, previewUrl, imageUrl, searchRegion, searchTerm, searchType, searchQuery, isNew, advertiserNameRedacted and scrapedAt.
How to see a competitor's Google ads by name, domain or advertiser ID
- Open the Actor in Apify Console and click Try for free.
- Put your advertisers into Advertiser URLs or domains — one per line. Any of these work:
- a website:
nike.com,www.booking.com, or any page URL on that site - an advertiser id:
AR18378488041124659201 - an advertiser page:
https://adstransparency.google.com/advertiser/AR18378488041124659201?region=USOr type brand names into Search by keyword or advertiser name (HubSpot,Booking) and leave the first field empty.
- a website:
- Optionally pick a Region (default: anywhere), an Ad format, a Platform and a date range (Shown on or after / Shown on or before).
- Set Maximum results — start with the default 20 to see the shape of the output.
- Click Start. The default input takes about five seconds; 1,000 ads take roughly 2-4 minutes.
- Open the Output tab or Export the dataset as JSON, CSV, Excel, XML or HTML.
To automate it, use the API tab (Node.js, Python, curl examples) or add a Schedule. For a competitor watch, turn on Only new ads (monitor mode) before you schedule it.
Input
Every field, its default and when you would change it:
| Field | Type | Default | When to change it |
|---|---|---|---|
startUrls | array of strings | ["nike.com", "booking.com"] | Always — this is your advertiser list. Website domains, advertiser ids (AR…) or Ads Transparency advertiser URLs. Pass many in one run and use searchTerm to tell the rows apart. |
searchQueries | array of strings | empty | Brand or advertiser names, e.g. ["HubSpot", "Booking"]. Each is matched against the Transparency Center's own search suggestions: the brand's verified website first (hubspot.com), then advertiser accounts with that name that carry a legal form such as Inc, GmbH or SRL, then such accounts whose name contains every word. Accounts without a legal form are not picked, because a keyword can be a person's name. When you set it, the example domains in startUrls are ignored. |
domains | array of strings | empty | Batch input for API and scheduled runs: website domains (["hubspot.com", "salesforce.com"]). Read exactly like startUrls; when you set it, the example domains in startUrls are ignored. |
advertiserIds | array of strings | empty | Batch input: bare advertiser ids (["AR10072600183532683265"]). Same rules as domains. |
maxAdsPerAdvertiser | integer | no cap | Cap per advertiser, domain or keyword match, so one large advertiser cannot use up maxItems in a batch. 50 domains with maxAdsPerAdvertiser: 20 and maxItems: 1000 give up to 20 ads each. |
maxAdvertisersPerQuery | integer | 3 | How many matched websites / accounts to take per keyword. 1 keeps only the best match. |
maxItems | integer | 20 | Raise it for production runs; it is your hard cap on rows and therefore on spend. Ads come back newest-active first, so even a small run shows the current campaigns. |
region | string | anywhere | Set an ISO alpha-2 country (US, GB, DE, ...) to keep only ads that ran in that country, and to decide which country's Ads Transparency page the url column points at. The country is sent to Google as a filter, and with ad details on the Actor also checks each ad's confirmed regions list: an ad not confirmed for that country is dropped, never billed, and replaced when possible. |
adFormat | string | any | Set text, image or video when you are studying one channel — for example image only, when you are collecting display creatives for a moodboard. |
platform | string | any | search, youtube, play, maps or shopping to keep only ads shown on that Google platform. Google applies the filter itself. |
dateFrom / dateTo | string | empty | Only ads shown within this range. A date (2026-09-01) or a relative value (30 days = 30 days ago). Either end may be left empty. Google keeps ads for one year after they were last shown. |
includeDetails | boolean | true | Off skips the per-ad lookup: about twice as fast, but without regions, platforms, impressions and targeting. Same price per ad. |
onlyNewAds | boolean | false | Monitor mode. Returns only ads that an earlier onlyNewAds run has not returned; ads already seen are skipped and never billed. A run with nothing new succeeds with an empty dataset. |
monitorStoreName | string | google-ads-transparency-monitor | Named key-value store on your own account that remembers the ads already returned. Use one name per schedule to keep separate watch lists. |
proxyConfiguration | object | Apify Proxy off | Leave it off: first requests go direct, and a failed or rate-limited request is retried through Apify Proxy (datacenter) automatically. Enable Apify Proxy (datacenter group) only if a run reports rate limiting; residential proxies are not needed and not recommended. |
A ?region= inside an advertiser URL overrides the Region field for that one entry, so you can mix countries in a single run.
Example input:
{"startUrls": ["nike.com", "booking.com"],"maxItems": 20,"region": "anywhere","adFormat": "any"}
Example batch: 3 competitor domains, up to 25 ads each:
{"domains": ["hubspot.com", "salesforce.com", "zendesk.com"],"maxAdsPerAdvertiser": 25,"maxItems": 75}
Example competitor watch (schedule it daily or weekly):
{"searchQueries": ["HubSpot", "Salesforce"],"region": "US","platform": "youtube","onlyNewAds": true,"monitorStoreName": "ads-monitor-crm","maxItems": 500}
On the first monitor run, set maxItems high enough to cover the advertiser's current ads; later runs read the newest ads first and stop paging after two pages in a row with nothing new.
How much does it cost to scrape ads transparency data?
This Actor uses pay-per-event pricing. The table below is the whole price list:
| Event | Charged when | Price |
|---|---|---|
| Actor start | Once per run, by the Apify platform (one event per GB of memory; the default is 1 GB). | $0.005 per run |
| Ad | One ad with status: ok is saved to the dataset. | $0.00149 per ad |
- 1,000 ads cost about $1.50 ($0.005 start + 1,000 × $0.00149).
- Rows with
statusnot_foundorerrorare never charged — an advertiser with no live ads costs you the start fee only. - In monitor mode (
onlyNewAds), ads already returned by an earlier run are skipped and never charged. - The Actor stops gracefully when your run's maximum charge is reached. Cap spending with Maximum results and with the run's Max total charge option.
- The free Apify plan's $5 of monthly credit covers about 3,350 ads in a single run.
How it compares
This Actor is the fast, cheap way to turn a list of competitor domains into a structured ad inventory. It is pure HTTP — about 1.1 requests per ad, and three consecutive staging runs of the default input finished 20 ads in 5.0–5.6 seconds on Apify's smallest machine. Brand-name and domain search, platform and date filters, per-ad country lists, EU impression ranges, a monitor mode that bills only new ads, and a tri-state status are the things it does better than a hand-rolled script.
It is not for you if you need ad headline text or landing-page URLs (the source publishes rendered previews, not copy), spend figures (this Actor does not output payer or spend data), or a search by the words inside the ads — the source resolves searches to advertiser accounts and verified websites, so keywords are matched against advertiser names, not ad copy. It also covers Google's own transparency disclosure only, not other ad platforms' libraries.
Integrations, API and AI agents
Results export to CSV, JSON, Excel, XML and HTML, and can be pushed to Google Sheets, Airtable, Slack or a CRM through Apify integrations and webhooks (n8n, Make and Zapier included). Add a Schedule to re-run a client or competitor list daily and diff the creatives.
The Actor can be called from the Apify API (Node.js, Python or curl — see the API tab), from the Apify MCP server, or from any AI agent: inputs are plain strings and every row is self-describing thanks to status and error, so an agent can tell "this advertiser runs no ads" apart from "the source could not be read".
Tips
- Start with the domain, not the advertiser id: one domain often covers several advertiser accounts (brand, regional entities, agencies), and each row tells you which one via
advertiserId. - Copy an
advertiserIdfrom a first run into a follow-up run to track exactly one account over time. - Sort by
daysShowndescending to find evergreen creatives, and byfirstShowndescending to see what launched this week. - Pass several advertisers in one run instead of many single-advertiser runs; you pay the start fee once.
- Not sure of a brand's domain? Put its name into
searchQueries, then reuse theadvertiserDomainoradvertiserIdfrom the output. - Turn
includeDetailsoff for quick inventories of thousands of ads when you do not need countries, platforms or impressions. - Keep
maxItemssmall while testing, then raise it.
FAQ
Can I search by keyword or by brand name? Yes, by advertiser or brand name: put HubSpot into searchQueries and the Actor finds the matching verified website and advertiser accounts through the Transparency Center's own search box, then returns their ads. It cannot search the words inside ads (such as "running shoes"), because Google does not offer that search.
How do I get only new ads every day? Turn on onlyNewAds, then add a Schedule. The first run returns the current ads; every later run returns only creatives that were not returned before, and charges only for those. Use a different monitorStoreName per watch list.
Can I filter by YouTube, Google Play or Maps? Yes, with platform. Google applies the filter itself. The platforms column comes from Google's EU/EEA disclosure, so for ads that never ran in the EU it can be missing even though the filter matched.
Is it legal to scrape ads transparency data? The Ads Transparency Center is a public transparency disclosure, published by Google so that anyone can look up who is advertising. Reading public pages is generally lawful, but you are responsible for how you use the output. Read the legal notice below and Google's terms of service, and do not collect personal data without a legitimate reason.
Why do I get several advertisers back for one domain? Large brands run ads through more than one Google Ads account: a global account, regional entities, and media agencies that verified the same website. A domain search returns all of them, and advertiserId and advertiserName tell you which account each ad belongs to.
What does daysShown mean exactly? It is the number of days the source recorded the ad as running. It is never larger than the span between firstShown and lastShown, and it is usually the better "is this ad working?" signal of the two.
Do I get the ad's headline text and landing page? No. The source publishes creatives as rendered previews, so you get previewUrl and imageUrl rather than copy or the advertiser's click-through URL. Open the preview to read the ad.
Can I use this Actor from an AI agent or MCP client? Yes. Every row is self-describing (status + error), inputs are plain strings, and results can be fetched via the dataset API or the Apify MCP server.
Why did I get fewer rows than maxItems? The advertiser publishes fewer ads for that region, format, platform and date range (or, in monitor mode, fewer new ones), or the run hit your Max total charge limit. Check the run log for "Stopping gracefully" and look at any not_found rows.
Do I need a proxy? No. The Actor works from Apify's datacenter IPs with the proxy off, which is the default. Turn on Apify Proxy (datacenter) only if a run reports rate limiting.
What if a field is missing? Optional fields are omitted when the source does not publish them. regions and regionCount are also omitted on the rare row whose per-ad lookup failed after retries — the rest of the row is still correct. If a field that should always be present is missing, open an issue in the Issues tab with the run ID.
Limitations
- The endpoint is undocumented. The Ads Transparency Center has no published public API; this Actor calls the same keyless JSON endpoints the website itself uses. They can change without notice, in which case rows come back as
errorand the Actor is updated quickly (report it in the Issues tab). - Coverage varies by country. Google's transparency disclosures differ per region and advertiser type: an advertiser can be fully listed in the EU and thinly listed elsewhere.
regionsshows what the source published, not what an advertiser truly bought. regionis checked twice. The country is sent to Google as a search filter, and with ad details on the Actor also checks each ad's confirmed country list and keeps only the ones that include it — dropped rows are never billed and one more search page is pulled in automatically to try to replace each one, up to the search's own page limit. If an advertiser has zero ads confirmed for that country, expect fewerokrows thanmaxItemsrather than an error; the run log states how many ads were dropped this way.- Platforms and impressions come from the EU/EEA disclosure. Google publishes
platforms, impression ranges andtargetingunder the EU Digital Services Act, so ads that ran only outside the EU usually lack them. - Keyword search matches advertiser names. A keyword is resolved through Google's own advertiser suggestions (up to 10 per keyword); accounts without a legal form in their name (Inc, GmbH, 株式会社 ...) are skipped, so a keyword never selects a private person's account. If a brand advertises under a different legal name, search its website domain instead.
- Political and election ads are disclosed differently from general ads. Political ads carry extra public data (payer and spend) that general ads do not have; this Actor does not output payer names or spend figures.
- No creative text and no landing-page URL. Ads are published as rendered previews, so the Actor returns
previewUrl/imageUrlrather than headline text or the advertiser's click-through URL. - No search inside ad text. Keywords are matched against advertiser names and verified websites, not against a phrase like "running shoes" inside the ads.
- Verified advertisers only. Advertisers that are not verified, and ads that have already been removed, are not in the source and cannot be returned.
- Rate limiting. Google throttles bursts from a single IP. The Actor keeps concurrency low, backs off automatically and retries a rate-limited request through Apify Proxy (datacenter); very large runs are best split into several scheduled runs, optionally through Apify Proxy (datacenter).
Related Actors
- LinkedIn Ad Library Scraper - use it to see the same competitors' LinkedIn ads: ad copy, CTA, landing page, dates and EU targeting, with the same batch and monitor inputs.
- Google Trends Scraper - use it to check whether the topics a competitor advertises are rising or falling.
- Google News Scraper - use it to see press coverage of a brand alongside the ads it is running.
- Pinterest Scraper - use it to see how the same brand or product shows up in organic Pinterest search.
- Tech Stack & DMARC Checker - use it to check the advertiser's landing-page domain before trusting an ad.
- Keyword Suggestions API - use it to build the keyword and negative-keyword lists for the ad groups you are benchmarking.
- Companies House Scraper - use it to verify a UK company's legal status, incorporation date, registered office and SIC codes.
- USPTO Trademark Scraper - use it to see which US trademarks a company or brand owns, with status and filing dates.
If this Actor saved you time, a rating or a save helps others find it. Found a problem? Open an Issue, we reply within 24 h.
Legal and data-protection notice
This Actor extracts only data that the Google Ads Transparency Center publishes publicly; it does not extract private user data such as e-mail addresses, phone numbers, gender or precise location, it does not log in, and it does not circumvent access controls. Advertiser names that look like a private person rather than a business (no legal form such as Inc, GmbH or 株式会社, not a website name, and not the name of the domain you typed) are redacted: the row keeps the ad but drops the advertiser name and id and sets advertiserNameRedacted to true. This check is automatic and cannot be perfect, so your results could still contain personal data, for example when a sole trader advertises under a trading name or the ad itself shows a person. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you are unsure whether your reason is legitimate, consult your lawyers. You are responsible for complying with Google's terms of service and applicable law when using the extracted data.
This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by Google LLC. All trademarks belong to their respective owners.