Google Ads Transparency Scraper & Ad Monitor
Pricing
Pay per event
Google Ads Transparency Scraper & Ad Monitor
Monitor competitor Google ads: export any advertiser's Search, YouTube, Shopping, Maps & Play ads from the Ads Transparency Center with headlines, OCR text for image ads, CTAs, regions and first/last shown dates. Monitor mode outputs only new or changed ads. No login.
Pricing
Pay per event
Rating
0.0
(0)
Developer
SingletonOps
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Features
Share
Monitor competitor Google ads from the public Google Ads Transparency Center: every Search, YouTube, Shopping, Maps and Play ad an advertiser runs, with headlines, OCR text for image ads, CTAs, regions and first/last shown dates. Monitor mode outputs only new or changed ads. No login. Built by SingletonOps (a brand of Vibex LLC).
Quickstart: your first run in 2 minutes
- Click Try for free (free Apify account, no card needed).
- The form is already filled in:
nike.com, region US, ads shown in the last 30 days, 20 ads, creative details and OCR on. Keep it, or replacenike.comwith your competitor's domain. - Click Start. Our test of this input (without the date filter) returned 20 ads in 11 seconds.
- Open the Output tab: headline, description, CTA, format, platforms and first/last shown dates per ad. Download as CSV, Excel or JSON.
- To keep watching: Save as task, turn on Only new or changed ads, and add a weekly schedule. Later runs output only
new,changedandstoppedads.
{"advertisers": ["nike.com"],"region": "US","dateFrom": "30 days","maxAds": 20}
A 20-ad first run costs about $0.03 at the proposed price (see Pricing; the Pricing tab on the Store page is authoritative).
Sample output (real run)
Real rows from a small test run on 2026-10-12 (input {"advertisers": ["nike.com"], "region": "US", "maxAds": 20}, 20 ads in 11 s). Text is shortened here; all 20 full records are in samples/first-run-nike-us-20-ads_2026-10-12.json, unedited except that the newer firstSeenDate, lastSeenDate and daysRunning fields were added offline from each row's own firstShown/lastShown. 19 of the 20 ads have been running for 180+ days, so longRunningOnly: true would keep 19.
| format | headline | description | CTA | textSource | firstShown | servedDays | daysRunning | platforms |
|---|---|---|---|---|---|---|---|---|
| TEXT | Nike® Official Site | Nike® offers ultimate selection of gear, accessori… | website | native | 2023-11-16 | 870 | 1062 | MAPS, SEARCH, SHOPPING, YOUTUBE |
| TEXT | Shop The Newest Nike® Styles | Nike® Kevin Durant basketball shoes for every athl… | website | native | 2023-11-17 | 901 | 1061 | MAPS, SEARCH, SHOPPING, YOUTUBE |
| TEXT | Nike® Golf Pants & More | Hit the links with the latest Nike® golf gear to c… | website | native | 2023-11-16 | 900 | 1062 | MAPS, SEARCH, SHOPPING |
| IMAGE | LeBron James Los Angeles Lakers City Edition … | — | — | native | 2026-06-03 | 91 | 132 | SEARCH, SHOPPING, YOUTUBE |
| TEXT | Kids Crew Socks. Nike.com | Shop The Official Nike Store For The Latest Nike S… | — | ocr | 2022-11-30 | 1362 | 1413 | MAPS, SEARCH, SHOPPING, YOUTUBE |
| TEXT | Shop Nike® Socks - Shop Nike® Online - Get Ac… | Comfortable, breathable, and performance focused. … | — | ocr | 2023-11-16 | 899 | 1062 | MAPS, SEARCH, SHOPPING, YOUTUBE |
| TEXT | — | Nike Clothing Is Designed For Performance And Tota… | website | native | 2022-11-30 | 1359 | 1413 | MAPS, SEARCH, SHOPPING, YOUTUBE |
The last row is a Maps/local ad with a dynamic headline: Google stores no headline text for it, so headline is null rather than guessed.
A domain returns every advertiser account whose ads point to it: this run found 3 (Nike, Inc. with 18 ads, Nike Retail BV and Nike Japan with 1 each). Group or filter by advertiserName, or use an AR… ID for one account. On your own domain, that's how you spot resellers and affiliates.
Monitor-mode rows look the same plus changeType and changedFields. Real example: samples/monitor-rerun-zalando-de-first3_2026-10-09.json: the first 3 rows of a real second monitor-mode run on Zalando SE in Germany, with that run's OUTPUT counts. Unchanged ads are checked but not saved, so they cost nothing.
Data comes from the public Google Ads Transparency Center. Search by advertiser name, website domain or advertiser ID and get clean, structured ad data: headlines, descriptions, images, YouTube videos, first and last seen dates, regions, platforms and impression ranges. Turn on monitor mode to get only the ads that are new or changed since the last run.
Use it as a Google ad library / ad spy tool for PPC competitor research: see the exact ad copy, creatives, CTAs and run dates of any competitor, export them to CSV/Excel/JSON, and get alerted when they launch new ads.
No browser, no login, no Google account. The actor calls the same lightweight JSON endpoints the Transparency Center website uses, so runs are fast and cheap.
What does Google Ads Transparency Center Scraper do?
- Resolves each input to Google advertiser IDs: names (fuzzy-matched, with the strongest advertiser picked), domains (every advertiser that runs ads for that site), IDs (
AR…) or full Transparency Center URLs. - Lists that advertiser's ads with your filters: region (any of 250 countries), date range, format (text, image, video) and platform (Search, YouTube, Shopping, Maps, Play).
- For each ad (optional, on by default) it fetches the creative details and the ad preview, and pulls out the headline, description, call to action, display URL, landing domain, image URLs and YouTube video URLs, plus per-region statistics (first and last shown, impression ranges, platforms). Text ads that Google archived only as a screenshot are read with OCR (on by default, see below).
- In monitor mode, it compares each ad with a snapshot from the previous run and outputs only
newandchangedads (plusstoppedones, see the FAQ), along with the exact fields that changed. - Writes a run summary (
OUTPUT) and a data-quality report (QUALITY_REPORT) to the key-value store.
Use cases for PPC teams
- Monday new-ad check without the clicking. Schedule a weekly run in monitor mode (
onlyNewOrChanged) for each competitor domain and read only thenew,changedandstoppedrows, withchangedFieldsshowing what moved. - Find the ads worth copying. Turn on
longRunningOnly(or setminDaysRunning, e.g. 90) to keep only ads a competitor has kept running for 6+ months, the ones their tests keep picking. Every row hasfirstSeenDate,lastSeenDateanddaysRunning; sort bydaysRunningornumServedDays. - See when a promotion really ended.
lastSeenDateis the last day Google showed the ad, so a sale ad whoselastSeenDatestopped moving has stopped running, whatever the landing page still says. - Catch offer and landing-page changes.
changedrows flag edits to headline, description, CTA orlandingDomain, often the first sign of a new promotion. - Spot resellers and affiliates on your brand. Search your own domain to see every advertiser running ads that point to it, including ones you didn't authorize.
- Agency audits and pitches in minutes. Export a prospect's full competitor ad library (Search, YouTube, Shopping) to Sheets or Excel, by country (
region) and date range. - Read image-only text ads. Built-in OCR fills
headlineanddescriptionfrom archived screenshots (textSource: "ocr"), so text ads aren't blank rows.
Also used by creative strategists (swipe files of YouTube, image and Shopping creatives by country), market-entry research (which advertisers are active in a region, on which platforms) and compliance teams (archive what an advertiser showed in a region and period).
Why use this actor?
| This actor | Typical Transparency scrapers | |
|---|---|---|
| Input | Advertiser name, domain, ID or URL, plus free-text search terms. Mix many in one run | Usually one URL or one query |
| Monitoring | Built-in onlyNewOrChanged mode with per-field change detection (changeType, changedFields) | Re-scrape everything and diff it yourself |
| Platforms | Every ad is tagged with the surfaces it ran on, including outside the EU (platform-membership scan) | Platforms often only for EU ads |
| Reliability | Retries with exponential backoff and jitter, proxy session rotation, automatic escalation to residential proxy when rate-limited, partial results instead of crashes | Fails the whole run on rate limits |
| Transparency | OUTPUT run summary and QUALITY_REPORT with field completeness, speed and estimated cost on every run | No quality metrics |
| Image-only text ads | Built-in OCR reads headline, description and display URL from the archived screenshot, marked textSource: "ocr", cached per creative | Empty fields |
| Cost | Pure HTTP/JSON plus lightweight WASM OCR, 512 MB default (256 MB works), about 1.5 KB of proxy traffic per ad | Often headless browsers |
What data can I extract?
| Field | Description |
|---|---|
advertiserId, advertiserName, advertiserLegalName, advertiserCountry, advertiserVerified | Who is paying for the ad |
creativeId, adDetailUrl | Stable ad ID and link to the ad on the Transparency Center |
format | TEXT, IMAGE or VIDEO |
firstShown, lastShown, numServedDays | When the ad ran (Google's timestamps) and how many days Google says it was served |
firstSeenDate, lastSeenDate, daysRunning | Ad longevity: first and last shown as UTC dates (YYYY-MM-DD), and daysRunning = days from first to last, counting both days (same day = 1). null when Google gives no date; never guessed |
regions, regionStats[] | Countries where it ran, with per-country dates, impression ranges and platforms |
platforms | GOOGLE_SEARCH, YOUTUBE, GOOGLE_SHOPPING, GOOGLE_MAPS, GOOGLE_PLAY |
impressionsMin, impressionsMax | Impression range (Google only publishes this for some regions, mainly the EU/EEA) |
headline, description, text, callToAction | Ad copy pulled from the rendered preview, or from the ad image via OCR |
textSource, ocrConfidence | native (from the preview), ocr (read from the ad image) or null (no text found); OCR confidence 0–100 |
imageUrls, videoUrls, previewUrl | Creative assets (YouTube links for video ads) |
displayUrl, landingUrl, landingDomain | Where the ad points |
variantsCount | Number of creative variations Google shows |
query | Which input and filters produced the row |
changeType, changedFields | Monitor mode only: new, changed or stopped, plus which fields changed (running when an ad stopped or started again) |
raw | Optional raw API payloads (includeRawData) |
Setup: how to monitor competitor Google ads
- Click Try for free / Start.
- Enter one or more advertisers (for example
nike.com,Zalando,AR15589870916631265281) or search terms. - Optionally choose a region, date range, format and platform.
- Set Max ads per advertiser (prefilled 20 for a quick first run; 100 when omitted via API).
- Run it, then download the data as JSON, CSV or Excel, or connect it to Make, Zapier, n8n, Slack or Google Sheets.
For ongoing competitor tracking, save the input as a task, turn on Only new or changed ads, and add a schedule (daily or weekly).
Input examples
All recent ads from a brand's domain
{"advertisers": ["nike.com"],"maxAds": 200}
Video ads on YouTube in Germany in the last 90 days
{"advertisers": ["Duolingo"],"region": "DE","format": "VIDEO","platform": "YOUTUBE","dateFrom": "90 days","maxAds": 100}
Discover advertisers by search term (top 2 matches each)
{"searchTerms": ["adidas", "running shoes"],"maxAdvertisersPerSearchTerm": 2,"dateFrom": "30 days","maxAds": 50}
Weekly competitor monitor (only new or changed ads)
{"advertisers": ["competitor-one.com", "Competitor Two GmbH", "AR15589870916631265281"],"region": "US","onlyNewOrChanged": true,"stateStoreName": "my-competitor-monitor","maxAds": 500}
Long-running ads only (6+ months): a competitor's proven winners
{"advertisers": ["nike.com"],"region": "US","longRunningOnly": true,"maxAds": 200}
longRunningOnly keeps ads with daysRunning of 180 or more. For another bar, set minDaysRunning instead (for example 90); if both are set, the larger one applies. Ads that don't qualify are skipped before their details are fetched where possible, and are never saved or charged. maxAds still counts every ad checked, so raise it to find more.
Fast, low-cost listing (no ad copy, about 1,000 ads per minute)
{"advertisers": ["amazon.com"],"includeCreativeDetails": false,"maxAds": 1000}
Dates accept absolute values (2026-01-31) or relative ones (30 days, 2 weeks, today).
Text from image-only ads (OCR)
For many text ads (especially older and EU ones), Google keeps only a screenshot of the ad. With extractTextFromImages on (the default), the actor reads the headline, description and display URL from that screenshot using Tesseract (WASM, no external service, no extra proxy traffic: images are downloaded directly).
- It runs only for
TEXTads whose preview has no text and that have an archived image, and only whenincludeCreativeDetailsis on. Ads with native text are never OCR'd. - The layout is read from the screenshot's colours: the blue line is the headline, the gray block under it is the description, the URL line above the headline is the display URL. Sitelinks, ratings and "App installed" rows are left out.
- Fields read this way carry
textSource: "ocr"andocrConfidence. The full list of recognised lines goes intotext. - Results are cached per creative in the
google-ads-transparency-cachekey-value store, so a monitor rerun (or any later run) never OCRs the same image twice. OCR text isn't used for change detection; a new image shows up as amediachange. ocrLanguagespicks the models. The default is English, German, French, Spanish, Italian, Dutch, Portuguese and Polish (bundled). You can add others (Nordic, Czech, Greek, Turkish, …); those are downloaded at run start.- OCR is CPU-bound. At 512 MB it takes about 5–9 s per image and at 2,048 MB about 1.4 s, at roughly the same cost per image. For large OCR-heavy pulls, raise the memory to go faster. Below 512 MB the actor limits OCR to 3 languages.
- Turn it off (
extractTextFromImages: false) when you only need ad metadata or want maximum speed.
On our test sample of 20 OCR'd ads, 16 of 20 headlines and 15 of 20 descriptions came out exactly right. Most of the remaining errors were one to four wrong accented characters (for example ß, å, ł). One ad had a product photo covering the text. All 20 display URLs were correct.
Output sample (one full JSON record)
{"advertiserId": "AR18378488041124659201","advertiserName": "Nike Retail BV","advertiserLegalName": "Nike Retail BV","advertiserCountry": "NL","advertiserVerified": true,"creativeId": "CR11779417970759958529","format": "TEXT","firstShown": "2025-10-24T16:24:40.000Z","lastShown": "2026-10-09T13:37:11.000Z","numServedDays": 351,"firstSeenDate": "2025-10-24","lastSeenDate": "2026-10-09","daysRunning": 351,"regions": ["AT", "DE", "LU"],"regionStats": [{"regionCode": "AT","regionName": "Austria","firstShown": "2025-10-25","lastShown": "2026-10-06","impressionsMin": 0,"impressionsMax": 1000,"platforms": [{ "platform": "GOOGLE_SEARCH", "impressionsMin": 0, "impressionsMax": 1000 }]}],"platforms": ["GOOGLE_MAPS", "GOOGLE_SEARCH"],"impressionsMin": 10000,"impressionsMax": 15000,"headline": "Aktuelle Workout-Schuhe","description": "Entdecke {Keyword:Nike schuhe} online auf Nike.com – der offiziellen Nike Website.","callToAction": null,"textSource": "native","ocrConfidence": null,"imageUrls": [],"videoUrls": [],"displayUrl": "nike.com","landingUrl": null,"landingDomain": "nike.com","variantsCount": 1,"adDetailUrl": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR11779417970759958529?region=anywhere","query": { "input": "nike.com", "type": "domain", "region": "anywhere", "format": "ALL", "platform": "ALL" },"detailsIncluded": true,"scrapedAt": "2026-10-09T13:54:51.775Z"}
The real previewUrl and text fields are included as well; they're left out here to keep the sample short. Rows produced in monitor mode also carry "changeType": "new" | "changed" | "stopped" and "changedFields": ["regions", "headline", …].
Key-value store records
OUTPUT: run summary with status (SUCCEEDED,PARTIALorFAILED), each query's resolution and ad counts, monitor counts (new, changed, unchanged), charging (payPerEvent,chargedEvents,chargeLimitReached), HTTP statistics, errors and estimated cost.QUALITY_REPORT: per-field completeness (overall and by format), ads per minute, proxy traffic, error categories and anyfeedbackyou sent with the run.
Alerts: get new competitor ads in Slack, email or a sheet
The actor finds the changes; Apify delivers them. A typical PPC alert setup:
- Save your input as a task with
onlyNewOrChanged: trueand a fixedstateStoreName(for examplecompetitors-us). Use one state store per monitor so tasks don't overwrite each other's snapshots. - Add a schedule to the task (weekly on Monday morning, or daily for fast-moving competitors).
- On the task's Integrations tab, connect Slack, email, Google Sheets, Zapier, Make or n8n, or add an Apify webhook on Run succeeded that points at your endpoint. Each run's dataset contains only
new,changedandstoppedads, so the alert is the change list, not the whole library. - Optional: set
reportIssueWebhookto get a POST when a run has errors, endsPARTIAL, or carriesfeedback, so a broken monitor never fails silently.
The first monitor run outputs the full baseline (every current ad as new) unless you turn off emitBaselineOnFirstRun. With it off, the first run only saves the snapshot and outputs (and charges) nothing. Monitor state is stored per query, so several tasks can share one store or stay separate.
How much does it cost?
The actor is pure HTTP plus an optional OCR step and runs at 512 MB by default. On our platform test runs, compute plus residential-proxy usage came to roughly $0.04–0.07 per 1,000 ads with full details and OCR off, and about $0.007 per 1,000 ads in list-only mode (includeCreativeDetails: false). OCR adds about $0.18–0.30 per 1,000 ads that actually need OCR, so the total depends on the advertiser. On nike.com (25% of ads needed OCR) it was $0.13 per 1,000 ads, and on Zalando DE (97% image-only) it was $0.23 per 1,000. These are platform usage figures from our tests, not the price.
Pricing
Pay-per-event, one event that matters:
| Event | Price | When it's charged |
|---|---|---|
ad | $0.0017 per ad ($1.70 per 1,000 ads) | One ad creative saved to the dataset |
apify-actor-start | $0.00005 per run | Apify's standard run-start event (covers the first seconds of compute) |
The Pricing tab on the Store page is always the authoritative price.
- You pay only for ads saved to the dataset. The
OUTPUTsummary andQUALITY_REPORTrecords are free. - In monitor mode (
onlyNewOrChanged) only new or changed ads are saved, so unchanged ads cost nothing. Example: a weekly monitor of 5 competitors that finds 40 new or changed ads costs about $0.07 per run. - A one-off audit pull of 1,000 ads costs about $1.70.
- Set Max cost per run in the run options to cap your spend. When the cap is reached, the actor stops cleanly, keeps what it has saved, and marks
charging.chargeLimitReached: trueinOUTPUT. In monitor mode, ads it didn't get to are still reported on the next run.
Proxy
By default the actor uses Apify Residential proxy. Only small JSON responses go through it, so traffic is about 1.5 KB per ad, and ad previews are fetched directly. Google rate-limits datacenter IPs aggressively. If you choose datacenter or no proxy and the actor hits repeated rate limits, it switches to residential automatically (proxyFallbackToResidential, default on).
FAQ
Is this a Google ad spy tool / ad library like the Meta Ad Library? Yes, for Google. It exports the same public data as the Google Ads Transparency Center, in bulk and in a structured format, so you can research competitors' ads across Search, YouTube, Shopping, Maps and Play.
Does it show ad spend, keywords or CTR? No. Google doesn't publish spend, targeted keywords or performance. You get the creatives, copy, dates, regions, platforms and (where Google publishes them) impression ranges.
What does textSource mean? native means the text came from Google's rendered ad preview, ocr means it was read from the archived ad image (with ocrConfidence), and null means no text was available.
Can I export to CSV or Google Sheets? Yes. Every Apify dataset downloads as JSON, CSV, Excel or XML, and integrations push it to Google Sheets, Slack, Make, Zapier or n8n.
Can I search by keyword, like "running shoes"? The Transparency Center only searches advertiser names and domains, not ad text. searchTerms returns the best-matching advertisers (and domains). For brand terms this works well. A generic phrase may match a small advertiser whose name contains those words.
Why are some text-ad headlines empty? For many older or EU text ads, Google only stores an image snapshot of the ad. With OCR on (default), the actor reads the text from that image (textSource: "ocr"). Headlines stay null when the ad has no image to read, or when the headline is dynamic (keyword insertion or local ads) and Google stores only a placeholder. The actor doesn't make up a headline in those cases.
Why are impressions missing? Google publishes impression ranges only for some regions (mostly the EU/EEA) and for political ads.
Is there a "Display" platform filter? No. The Transparency Center's platform filter only offers Search, YouTube, Shopping, Maps and Play, so the actor offers the same five.
Does it detect removed ads? Yes, in monitor mode. An ad is saved once as changeType: "stopped" when its lastShown date is at least stoppedAfterDays days old (default 3) and didn't advance since the previous run, or when it is missing from a complete listing two runs in a row (listings cut short by maxAds, an error or a cost limit never count). A stopped ad that runs again comes back as changed with changedFields: ["running"]. Turn this off with reportStoppedAds: false.
How is daysRunning counted? It's lastSeenDate minus firstSeenDate plus 1, so both the first and the last day count (an ad shown on one day only has daysRunning: 1). The dates are the UTC calendar dates of Google's firstShown and lastShown. It's the calendar span, not numServedDays (the days Google says the ad was actually served): an ad that paused for a while has a lower numServedDays. Google counts days in its own time zone, so the two can also differ by a day. If either date is missing, daysRunning is null; with minDaysRunning or longRunningOnly on, those ads are left out. Our Meta Ad Library monitor uses the same three fields and the same definition.
Does the long-running filter work in monitor mode? Yes. Only ads that pass the filter start being tracked, so an ad shows up as new the run it first reaches the bar. Ads already tracked stay in, so their changes and their stop are still reported. Turning the filter on starts its own baseline (it doesn't reuse the snapshot of the same query without the filter). stopped rows for tracked ads are always reported; they carry lastSeenDate but firstSeenDate/daysRunning are null because the snapshot doesn't keep the first shown date.
What happens if an advertiser doesn't exist? That query is reported as NOT_FOUND in OUTPUT, and the other queries still run. If every query fails, the run fails with a clear message.
How do I report a problem? Use the Issues tab, or put a note in the feedback input field. It's saved to QUALITY_REPORT and reviewed weekly. You can also set reportIssueWebhook to get a POST whenever a run has errors.
Limits
- Only public Transparency Center data: no spend, keywords, audiences or click data.
- Google may rate-limit heavy usage; the actor retries and falls back to residential proxy, but very large pulls can end as
PARTIAL. - The actor paginates (40 ads per page) until
maxAdsis reached or there are no more pages.maxAdsapplies to each advertiser input, domain, or resolved search-term advertiser. WithminDaysRunning/longRunningOnly,maxAdscounts ads checked, not ads saved. - OCR text can contain small character errors, mostly accented letters in languages outside
ocrLanguages, and text covered by a product image. CheckocrConfidenceandtextSource. landingUrlis rarely exposed by Google.landingDomaincomes from the display URL or the preview.- Date filters cover what the Transparency Center exposes (the actor searches from 2018-01-01 onward when no start date is set).
- With details on and OCR off, our tests ran at about 100–170 ads per minute. OCR is CPU-bound: at 512 MB, expect roughly 10–25 ads per minute when most ads are image-only, or about 35 per minute at 2,048 MB. For very large pulls, use list-only mode first.
Legal
This actor only collects data that Google publishes in the public Ads Transparency Center, without logging in. It doesn't collect personal data about individuals. Still, the results can include advertiser names and other information. Make sure your use complies with Google's Terms of Service and the laws that apply to you (for example GDPR). If you're unsure, consult your lawyer. You can read more in Apify's blog post on the legality of web scraping.
Support
Found a bug or need a field? Open an issue on the Issues tab. We review issues, feedback and quality reports every week.
Built and maintained by SingletonOps, a brand of Vibex LLC. Also from SingletonOps: Meta Ad Library Monitor (new competitor Facebook and Instagram ads), RSS Change Monitor and Sitemap Change Monitor.