Google Ads Transparency Scraper — Copy, Regions, Impressions avatar

Google Ads Transparency Scraper — Copy, Regions, Impressions

Pricing

from $1.00 / 1,000 ads

Go to Apify Store
Google Ads Transparency Scraper — Copy, Regions, Impressions

Google Ads Transparency Scraper — Copy, Regions, Impressions

Get the ads a domain, brand or advertiser runs on Google from the Ads Transparency Center (Google's ad library): ad text, with OCR for image-only ads, image, YouTube ID, first/last shown, per-country impressions (EEA/TR), platforms, targeting, topic, Shopping price and legal name.

Pricing

from $1.00 / 1,000 ads

Rating

0.0

(0)

Developer

Berkan Kaplan

Berkan Kaplan

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Get the ads a website, brand or advertiser runs on Google — Search, YouTube, Maps, Play and Shopping — straight from the public Google Ads Transparency Center. One row per ad with the ad text — read from the ad's picture (OCR) when Google keeps only a picture — image or preview, Shopping price, YouTube video ID, first and last shown date, per-country impressions and platform breakdown (EEA and Turkey), audience-targeting approach, topic and the advertiser's legal name.

No Google account, no API key, no browser.

Quick start (API)

curl -X POST "https://api.apify.com/v2/acts/foxlabs~google-ads-transparency-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries": ["nike.com"], "maxAdsPerQuery": 20}'

What you get

GroupFields
AdvertiseradvertiserName, advertiserLegalName, advertiserId, advertiserCountry, advertiserDunsNumber (where Google publishes it)
AdcreativeId, format (TEXT / IMAGE / VIDEO), firstShown, lastShown, daysShown, imageUrl, previewUrl, transparencyUrl
Ad copyadTexts (text lines in order), callToAction, displayUrl, landingUrl, landingDomain, youtubeVideoId, isShoppingAd, productTitle, price, merchantName, shoppingService, app (ID, name, store, category, developer of app-install ads)
Reach (EEA + Turkey)impressionsEeaTrLow / High, surfacesEeaTr (impressions per platform), regions[] (per country: first / last shown, impression range, platform breakdown)
Targetingtargeting.demographics, geoLocation, contextualSignals, customerLists, topicsOfInterest — each INCLUDED, EXCLUDED, INCLUDED_AND_EXCLUDED or UNUSED
Classificationtopic (Google's ad topic), productCategory (some Shopping ads), variationCount
StatusdetailStatus, adCopyStatus (ok from the preview, ocr read from the picture, image-placeholder, …), ocrConfidence (0–100), query, queryType, regionFilter, scrapedAt, error; isNew in monitoring mode

Sample output

A real row (trimmed) from a run on 2026-09-23, query Decathlon, region France:

{
"advertiserName": "Decathlon France SASU",
"advertiserLegalName": "Decathlon France SASU",
"advertiserId": "AR15666691663760195585",
"advertiserCountry": "FR",
"creativeId": "CR18395479902410244097",
"format": "TEXT",
"firstShown": "2026-01-21T16:26:15.000Z",
"lastShown": "2026-09-23T14:37:34.000Z",
"daysShown": 233,
"adTexts": ["DECATHLON - SUPPORT DE CADENAS DE CADRE DE VELO RING-LOCK - antivol - velo voyage - Decathlon"],
"displayUrl": "Decathlon.fr",
"isShoppingAd": true,
"productTitle": "DECATHLON - SUPPORT DE CADENAS DE CADRE DE VELO RING-LOCK - antivol - velo voyage - Decathlon",
"shoppingService": "Yteo",
"transparencyUrl": "https://adstransparency.google.com/advertiser/AR15666691663760195585/creative/CR18395479902410244097?region=FR",
"targeting": {
"demographics": "UNUSED",
"geoLocation": "INCLUDED_AND_EXCLUDED",
"contextualSignals": "INCLUDED_AND_EXCLUDED",
"customerLists": "UNUSED",
"topicsOfInterest": "UNUSED"
},
"impressionsEeaTrLow": 6000,
"impressionsEeaTrHigh": 7000,
"surfacesEeaTr": [
{ "surface": "YOUTUBE", "impressionsLow": 0, "impressionsHigh": 1000 },
{ "surface": "SHOPPING", "impressionsLow": 0, "impressionsHigh": 1000 },
{ "surface": "SEARCH", "impressionsLow": 6000, "impressionsHigh": 7000 }
],
"regions": [
{ "countryCode": "FR", "countryName": "France", "firstShown": "2026-01-21", "lastShown": "2026-09-23", "impressionsLow": 6000, "impressionsHigh": 7000 }
],
"variationCount": 3,
"detailStatus": "ok",
"adCopyStatus": "ok"
}

Input & filters

InputWhat it doesDefault
queriesDomains (nike.com), brand names (Nike), advertiser IDs (AR…) or Transparency Center URLs. The same advertiser given twice in one run (its ID and its URL) is run once—
regionOnly ads shown in this country (243 countries)anywhere
adFormatall, text (includes Shopping product ads), image, videoall
platformall, search, youtube, maps, play, shoppingall
datePresetAds shown during any, last7, last30, last90, last365 or custom. dateFrom / dateTo (YYYY-MM-DD) also work on their own; a fixed period takes precedence over themany
maxAdsPerQueryStop after this many ads per query (up to 100,000). The Console form starts at 10 for a quick first run (12–132 s in four test runs)100
maxAdvertisersPerQueryBrand names only: how many of the brand's advertiser entities to include1
includeDetailsRegions, impressions, platforms, targeting, topic (one extra request per ad)on
includeAdCopyText lines, CTA, display URL, YouTube ID, Shopping title, price and merchant (one extra request per ad)on
ocrImageAdsRead the text of ads Google keeps only as a picture (OCR; English, German, French, Spanish, Portuguese, Italian, Dutch, Polish, Turkish)on
includeAdvertiserDetailsLegal name, country, D-U-N-S numberon
onlyNewAds + monitorNameMonitoring: only ads this monitor has not returned beforeoff
proxyConfiguration, autoProxyFallbackProxy is not needed; the Actor switches to Apify residential proxy by itself if Google rate-limits itoff / on

Region, format, platform and dates are applied by Google itself, so a filtered run does not download ads it then throws away. Invalid input (no query, a date not in YYYY-MM-DD form, dateFrom after dateTo) stops the run at once with the reason in its status message.

Example inputs (copy & paste)

A competitor's YouTube video ads from the last 30 days (ads this new have no impression ranges yet, see Data quality):

{ "queries": ["nike.com"], "adFormat": "video", "platform": "youtube", "datePreset": "last30", "maxAdsPerQuery": 200 }

A brand's ads in France with per-country reach:

{ "queries": ["Decathlon"], "region": "FR", "maxAdsPerQuery": 100 }

Weekly monitor of new ads from several competitors (schedule it weekly):

{ "queries": ["hubspot.com", "salesforce.com"], "onlyNewAds": true, "monitorName": "crm-competitors", "datePreset": "last7", "maxAdsPerQuery": 2000 }

Several entities of a brand, fast (no ad copy). maxAdsPerQuery is shared by all matched entities, and the biggest one usually fills most of it:

{ "queries": ["Decathlon"], "maxAdvertisersPerQuery": 10, "includeAdCopy": false, "maxAdsPerQuery": 1000 }

Use cases

  • Competitor creative research: see which messages, offers and formats a competitor keeps running, with the image or preview of every ad and its text, read from the picture when Google keeps only a picture. daysShown and lastShown separate long-running ads from tests.
  • Shopping and offer tracking: product titles, prices and merchants of Shopping ads, and the display URLs and text of search ads, show what is being pushed.
  • EU reach analysis: impression ranges per country and per platform for ads that have run in the EEA or Turkey for about three months or more.
  • New ad alerts: schedule onlyNewAds daily or weekly and connect the dataset to Slack, email or a sheet. New ads arrive without impression ranges; Google adds those later.
  • Prospecting: find which companies advertise and on which platforms, with their legal name, to qualify marketing and agency leads.

Performance & throughput

Measured on the Apify platform (details and ad copy on; 512 MB memory without OCR, 1 GB with OCR):

RunAdsTime
nike.com (2026-09-23)4024 s
nike.com, YouTube video ads, last 30 days (2026-09-23)5029 s
nike.com + Decathlon (Wednesday 2026-09-23)6008 min (74 ads per minute)
Same input three days later (Saturday 2026-09-26)6006.6 min (91 ads per minute)
hubspot.com + salesforce.com search ads, OCR on (2026-09-26)40, 24 of them pictures111 s
nike.com + hubspot.com, OCR on (2026-09-26)80, 44 of them pictures3.6 min
nike.com, the form's starting input, OCR on (2026-09-27, four runs)10, 3–7 of them pictures12–132 s
nike.com, OCR on (2026-09-27)100, 60 of them pictures4.5 min

Listing needs one request per 40 ads; details and ad copy need one request per ad each. Reading an ad's picture (OCR) takes 0.6–7.5 s per picture at the default 1 GB memory, depending on how busy the platform's server is, so advertisers whose ads are mostly pictures run at roughly 20 ads per minute (100 nike.com ads, 60 of them pictures, in 4.5 min) and slower when the server is busy; more memory gives the run more CPU, and turning ocrImageAds off brings the speed back to the rows above. The Actor needs at least 512 MB: with OCR, memory use peaked at about 240–340 MB in these runs, and a run at 256 MB was stopped for lack of memory. Requests are spaced to stay under Google's rate limit. In some runs Google limited the platform's IP within the first 25–50 requests; the run then continues through Apify residential proxy by itself. With the default one-hour timeout and details and ad copy on, a run delivers roughly 4,000–5,000 ads; turn those options off or raise the timeout for more.

Integrations

Use the dataset from the API, export CSV / Excel / JSON from the console, or connect it to Make, Zapier, n8n, Google Sheets or Slack with Apify integrations. Schedule the Actor for monitoring.

Data quality

Share of ads with the field filled, measured on the Apify platform: the same 600 ads of nike.com and Decathlon on 2026-09-23 and 2026-09-26, 1,200 ads of hubspot.com, nike.com and Decathlon, and 50 YouTube video ads of nike.com. Several fields depend a lot on the advertiser, so the notes under the table matter.

FieldFilled
Advertiser name and ID, creative ID, format, first / last shown, days shown, countries100%
Advertiser legal name99–100%; 16% in the YouTube sample, where 40 of 50 ads ran through a media agency's account
Impressions and platforms per country (EEA and Turkey)70–82% (ads running there for about three months or more: 99%; newer ads: 0%)
Targeting approach77–86%
Topic38–55%
Ad text lines, OCR onhubspot.com + salesforce.com search ads 85% (34 of 40; the other 6 pictures are empty archive placeholders), nike.com + hubspot.com 99% (79 of 80), hubspot.com 100 of 100
Ad text lines, OCR offDecathlon 78–86%, nike.com 34–37%, hubspot.com 3.5%
Display URL · Shopping product title49–52% · 36–45% (nike.com + Decathlon)
YouTube video ID — YouTube video ads88%
Landing page URL · call to actionunder 1% in the mixed runs, 6% of the YouTube video ads (only previews that carry a click URL: video, app and some local ads)
Shopping product category6–9% of Shopping ads
D-U-N-S number7–14%

Every test run returned unique ads (no duplicate creativeId per query in 3,100 ads checked). The five targeting categories and the Shopping and YouTube platform codes were cross-checked, ad by ad, against Google's BigQuery dataset.

What to expect, by design:

  • Many ads are archived as pictures, and their text is read by OCR. Google keeps a large share of search ads, and most image ads, only as a picture of the ad (hubspot.com: 12 of 12 text ads in one test). With ocrImageAds on (the default), the Actor reads the text in the picture: those rows have adCopyStatus: "ocr", the text lines in adTexts, the display URL in displayUrl and ocrConfidence (0–100). In a review of 20 such ads, the headline and description came out right in all 10 search ads (near word-for-word) and in 8 of 9 display ads; text drawn inside the ad's graphic is sometimes missing or jumbled, and typical OCR slips appear ("AI" read as "Al", a lost accent). Some pictures in Google's archive hold no ad at all, only "Collapsed ad on mobile / Expanded ad" labels: those rows get adCopyStatus: "image-placeholder" and no text (6 of 40 hubspot.com / salesforce.com search ads). OCR covers Latin-script languages; other scripts come out empty or garbled.
  • Impressions appear about three months after an ad starts. Google publishes impression ranges only for the EEA and Turkey, and only for ads that have run there for roughly 90 days: none of 98 ads first shown in the EEA in the last 90 days had them, against 99% of 1,828 older ads. Other countries never have impression ranges; their rows list the country and its last-shown date with impressionsLow / impressionsHigh set to null.
  • A domain query returns the ads that lead to that domain, whoever runs them. For hubspot.com, 120 of 400 ads came from 74 other advertisers (partners, resellers, individuals). Query the AR… advertiser ID to get one account only.
  • The advertiser is the paying account, often an agency: 40 of 50 nike.com YouTube ads ran through "Mediabrands Netherlands B.V.", which has no published legal name.
  • Shopping fields. price is the price line as shown ("149,99 €"). merchantName is the store line; a retailer's own listings (Decathlon) have none, the store is in displayUrl.
  • Details are almost always there. Every one of the 3,400+ ads listed in our test runs came back with details. A creative opened directly by URL for which Google serves none leaves one free row with error: "empty: Google shows no details for this creative." Rows of creative-URL queries have no daysShown.
  • Previews Google cannot draw are marked adCopyStatus: "preview-unavailable" (8 of 600 ads in the latest run).
  • Template tokens are removed, keyword insertion is kept. Placeholders such as [Price] or <Rating (Reviews)> are not values and are dropped. Dynamic keyword insertion such as {Keyword: Housse} is what the advertiser wrote and is kept.
  • D-U-N-S numbers come from the mapping Google publishes in the Transparency Center. It covers about 6,500 advertiser accounts, so the field is empty for most advertisers.

Pricing

Pay per event: ad for every delivered ad, plus ad-detail when details were returned and ad-copy when text or other copy fields were read, from the preview or from the ad's picture (OCR). Pictures with no readable text are not charged as ad copy. Queries that return no ads, and error rows, are not charged. An advertiser given twice in one run is run once, so its ads are not charged twice. See the Pricing tab for the prices.

FAQ

Do I need a Google account or an API key? No. The Actor reads the same public data as the Ads Transparency Center website.

Why are impressions empty? Google publishes impression ranges only for ads shown in the EEA and Turkey, and only once an ad has run there for about three months. US-only ads and new ads have none.

Why do some ads have no text? Google archives many ads only as a picture. With ocrImageAds on, their text is read from the picture (adCopyStatus: "ocr"). Rows still without text are pictures that hold no ad (image-placeholder), pictures without readable text (image-no-text), or ads in non-Latin scripts.

What does daysShown mean? The number of days Google reports the ad as shown.

How fresh is the data? It is read live from the Transparency Center when the run starts.

Can I get only new ads? Yes. Turn on onlyNewAds and give the monitor a name. Each run returns only ads this monitor has not returned before and remembers them, also when a run is aborted. A run checks up to 10,000 listed ads per query (listing is cheap; details and ad copy are fetched only for new ads) and delivers at most maxAdsPerQuery new ones. Pair it with a datePreset such as last7 so the check covers everything shown in that period. A query with no new ads leaves one free row with error: "empty: No ads that were not already seen in earlier runs."; filter out rows with an error before you forward the dataset to Slack or a sheet.

What if a brand has several advertiser accounts? Brands often advertise through several legal entities. Raise maxAdvertisersPerQuery, or query the domain instead of the name (a domain also brings ads of other advertisers that link to it).

Troubleshooting

  • "No advertiser matches": try the website domain or the AR… advertiser ID from the Transparency Center URL. Brand names are matched the way Google's own search box matches them, accents included; when no advertiser carries the exact name, the log and the SOURCE_REPORT record say that the closest match was used.
  • A query returned nothing: the dataset has a row with error explaining why, and the SOURCE_REPORT record in the key-value store lists every query's outcome.
  • Slow run: turn off includeDetails / includeAdCopy for large lists, or narrow the date range.
  • This Actor is not affiliated with Google. It reads the public Ads Transparency Center, whose web interface can change.
  • Impressions are ranges, as published by Google.
  • Targeting: all five categories were cross-checked, ad by ad, against Google's public BigQuery dataset of the Transparency Center (bigquery-public-data.google_ads_transparency_center).
  • The data describes advertisers and their ads. It contains no personal data about people who saw the ads. Advertiser names are published by Google and can be the names of individuals (sole traders); treat those as personal data where GDPR or similar laws apply.
  • You are responsible for how you use the data.

Support

Open an issue on the Issues tab with the run ID and the query.

Changelog

0.1.14 — 2026-09-27

The Console form starts at 10 ads per query (API calls without maxAdsPerQuery still get 100), so a first run is quick (12–132 s in four test runs); minimum memory is 512 MB, because OCR does not fit in 256 MB. 0.1.15 corrects the measured speeds in this README. See CHANGELOG.md.

0.1.13 — 2026-09-26

Text of image-only ads: Google keeps many ads only as a picture, and the Actor now reads the text in the picture (OCR, on by default, ocrImageAds). Such rows have adCopyStatus: "ocr" and ocrConfidence; pictures that hold no ad are marked image-placeholder. hubspot.com ads with text went from 3.5% to 100 of 100 in a test run. See CHANGELOG.md.

0.1.9 — 2026-09-26

Fixes from the pre-publication checks: monitoring now finds new ads among still-running ones and remembers delivered ads when a run is aborted; dateFrom / dateTo work without choosing "Custom dates"; invalid input stops the run with a clear status message; Shopping ads get a price field and merchantName no longer holds prices; the same advertiser given twice is run once; creative URLs keep the YouTube ID; icons and invisible characters are no longer reported as ad content. See CHANGELOG.md for the full list.

0.1 — 2026-09-23

First version. See CHANGELOG.md for the full list.