Google Ads Transparency Competitor Monitor
Pricing
from $1.00 / 1,000 google ad creative results
Google Ads Transparency Competitor Monitor
Monitor competitor Google Ads Transparency creatives and detect new or changed ads from public transparency data.
Pricing
from $1.00 / 1,000 google ad creative results
Rating
0.0
(0)
Developer
Juyeop Park
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Monitor competitor Google Ads Transparency Center creatives from public transparency data, export stable creative IDs, and detect newly launched, changed, or no-longer-observed ads across scheduled Apify runs.
This Actor is designed as a schedule-ready competitor intelligence monitor. It is not a complete landing page scraper, not a complete ad copy extractor, and not a replacement for the official Google Ads API.
5-minute weekly competitor monitor quickstart
Use this flow to turn one bounded competitor search into a saved baseline and then compare the same search on an Apify Schedule.
- Choose one source and a stable monitor name. Start with one domain, as below, or use one known Google Ads Transparency Center
advertiserId. KeepmonitorIdstable for this exact competitor, region, and cadence. - Run the Actor once to create the baseline. Copy this input into the Actor and start a run:
{"domains": ["nike.com"],"region": "US","maxAdsPerDomain": 10,"monitorId": "nike-us-weekly","autoDiff": true,"saveMonitorState": true,"includePreviewParsing": false,"proxyConfiguration": {"useApifyProxy": true}}
On the first successful run with current creatives and no previous baseline, diff_source is none. The Actor writes the current rows to the Dataset, saves their Dataset/run reference for this monitorId, and writes OUTPUT plus a Markdown REPORT to the run's key-value store.
- Create an Apify Schedule. In Apify Console, create a time-based Schedule for the same Actor and the same input, then choose your cadence. The Actor does not create the Schedule for you. Do not change the domain, advertiser ID, region, or
monitorIdbetween the baseline and repeat run. - Review each repeat. When a valid saved baseline can be loaded,
diff_sourcebecomessaved_monitor_state. OpenREPORTfor a human-readable summary, then inspect Datasetchange_statusvalues:new,existing,changed, andnot_observed. Dataset rows also exposestable_key,monitor_id, andbaseline_dataset_idfor traceability.
Do not put secrets, credentials, client names, or personal data in monitorId; use a non-sensitive label such as nike-us-weekly. This Actor polls public Google Ads Transparency Center data and discovery/preview parsing is best-effort. It is not real-time; changes are visible only after a scheduled run completes. It is not an official Google Ads API and does not provide spend, targeting, conversion, impression, or final redirect metrics.
Current visible pay-per-event prices are row- and memory-based: creative-result is currently $0.001 per emitted current creative row, while apify-actor-start is currently $0.00005 per GB of configured memory at run start. Historical not_observed rows do not trigger another creative-result event. Do not treat these event prices as a total-cost or revenue estimate; the actual charge shown by Apify depends on configured memory, emitted rows, run settings, and applicable platform usage.
What it does
- Searches public Google Ads Transparency Center data by competitor domain, advertiser ID, or both.
- Best-effort discovers advertiser candidates for each domain, then conservatively selects only candidate IDs corroborated by exact-domain creative results.
- Emits one dataset item per current creative using the stable key
advertiser_id::creative_id. - Captures advertiser ID/name/domain, creative ID, first/last seen dates, creative type code, media URL, preview URL, and fetch timestamp.
- Optionally parses public creative preview scripts for best-effort CTA, ad text snippets, and landing URLs.
- Diffs the current run against either an explicit previous dataset/run or a saved
monitorIdbaseline. - Marks creatives as
new,existing,changed, ornot_observedso scheduled users can see what changed since the last run. - Writes a compact JSON
OUTPUTsummary and human-readable MarkdownREPORTto the key-value store.
Good use cases
- Scheduled competitor ad monitoring for ecommerce, SaaS, agencies, or brand teams.
- Detecting new Google/YouTube/Display creative launches from known competitor domains.
- Checking which ads disappeared or changed after each weekly or daily run.
- Exporting stable creative IDs and media/preview URLs for downstream research.
- Building a lightweight ad-change report without Google login, cookies, or private account access.
Input examples
Small single-domain monitor
{"domains": ["adidas.com"],"region": "KR","maxAdsPerDomain": 10,"includePreviewParsing": true,"proxyConfiguration": {"useApifyProxy": true}}
Domain discovery monitor
Advertiser discovery is enabled by default. best_match selects one advertiser only after the candidate advertiser ID is corroborated by creatives returned for the exact input domain; a standalone brand or domain suggestion is not enough. Use all_verified_domain_matches to select up to maxAdvertisersPerDomain, or set includeAdvertiserDiscovery=false to preserve domain-only collection. Each selected advertiser ID is queried as an additional advertiser source, and maxAdsPerDomain applies independently to every domain or advertiser source. advertiserSelection=manual_only skips discovery and domain collection and queries only explicit advertiserIds. The discovery candidates are not billed by themselves; only emitted current creative rows can trigger the creative-result event.
{"domains": ["nike.com"],"includeAdvertiserDiscovery": true,"advertiserSelection": "best_match","maxAdvertisersPerDomain": 3,"region": "KR","maxAdsPerDomain": 10,"includePreviewParsing": false}
First baseline run for a scheduled monitor
Run this once to create the baseline. The Actor saves the current dataset under monitorId, so later runs can compare automatically.
{"domains": ["nike.com"],"region": "KR","maxAdsPerDomain": 25,"monitorId": "nike-kr-weekly","autoDiff": true,"saveMonitorState": true,"includePreviewParsing": true,"proxyConfiguration": {"useApifyProxy": true}}
Later schedule run with automatic diff
Use the same monitorId in your Apify schedule. You do not need to paste previousDatasetId or previousRunId; when autoDiff=true, the Actor loads the last saved dataset and reports newly seen, changed, existing, and no-longer-observed ads.
{"domains": ["nike.com"],"region": "KR","maxAdsPerDomain": 25,"monitorId": "nike-kr-weekly","autoDiff": true,"saveMonitorState": true,"includePreviewParsing": true,"proxyConfiguration": {"useApifyProxy": true}}
Multiple competitors for a scheduled run
{"domains": ["nike.com", "samsung.com", "temu.com"],"region": "KR","maxAdsPerDomain": 25,"monitorId": "kr-competitors-weekly","autoDiff": true,"saveMonitorState": true,"includePreviewParsing": true,"proxyConfiguration": {"useApifyProxy": true}}
Direct advertiser ID
Use this when you already know the Google Ads Transparency Center advertiser ID. Set domains to an empty array for a pure advertiser-ID run, so no domain source is mixed into the results.
{"domains": [],"advertiserIds": ["AR14017378248766259201"],"region": "KR","maxAdsPerDomain": 10,"monitorId": "adidas-advertiser-kr","autoDiff": true,"includePreviewParsing": false}
Explicit diff against a previous run or dataset
Use either previousRunId or previousDatasetId from an earlier run when you want to control the baseline manually. previousDatasetId takes highest precedence, then previousRunId, then saved monitorId state.
{"domains": ["adidas.com"],"region": "KR","maxAdsPerDomain": 25,"previousRunId": "LAST_RUN_ID","monitorId": "adidas-kr-weekly","includePreviewParsing": true,"proxyConfiguration": {"useApifyProxy": true}}
Experiment without updating the saved baseline
Set saveMonitorState=false when you want a one-off test run that should not become the next baseline for the schedule.
{"domains": ["nike.com"],"region": "KR","maxAdsPerDomain": 5,"monitorId": "nike-kr-weekly","autoDiff": true,"saveMonitorState": false,"includePreviewParsing": false}
How scheduled auto-diff works
- Choose a stable
monitorId, for examplenike-kr-weeklyorclient-a-saas-us. - First run: no previous dataset is available, so the run is treated as a baseline and
diff_sourceisnone. - The run saves a small monitor state record with the current run ID, dataset ID, item count, domains, advertiser IDs, and region. It does not store raw preview scripts or page HTML.
- Second and later runs with the same
monitorIdandautoDiff=trueuse the saved dataset as the baseline.diff_sourcebecomessaved_monitor_state. - If you provide
previousDatasetId, it overrides everything. If you provide onlypreviousRunId, it overrides saved state. - If
saveMonitorState=false, the current run is not written as the next baseline.
Output fields
Each dataset item includes:
input_domain/input_advertiser_idmatched_input_domains/matched_input_advertiser_ids- Optional discovery provenance:
source_advertiser_discovery_status,source_advertiser_selection_reason,source_discovered_advertiser_id,source_discovered_advertiser_name, andsource_discovery_confidence advertiser_id,advertiser_name,advertiser_domaincreative_idstable_keyasadvertiser_id::creative_idfirst_seen,last_seenregion,region_codecreative_type_codemedia_url,preview_urlfetched_atcoverage_statuscta,ad_text_snippet,landing_url,landing_statuschange_statusandchanged_fieldswhen diffing is enabledmonitor_id,monitor_state_key,diff_source, andbaseline_dataset_idfor scheduled monitor runs
Diff source guide
none: baseline run; no explicit previous dataset/run and no saved monitor baseline was used.saved_monitor_state: the Actor used the last saved dataset for the same monitor.explicit_previous_dataset: you providedpreviousDatasetId; it took precedence.explicit_previous_run: you providedpreviousRunId; it took precedence over saved state.
Coverage status guide
ok: core creative metadata was collected.zero_results: source returned no creatives.partial_preview_parse: preview parsing found at least some optional CTA/text/landing signal, but coverage is still partial.preview_parse_failed: preview script was present but could not be parsed/fetched.blocked_or_unparseable: public RPC response was blocked or not parseable for that source.
Key-value store artifacts
OUTPUT: JSON summary with source counts, diff totals, monitor state, and limitations.OUTPUT.advertiser_discovery: best-effort candidate, selected-ID, selection-reason, and zero-result status evidence by domain.REPORT: Markdown report for quick human review, including whether the run was a baseline or saved-state diff.
Pricing note
The current visible pay-per-event price for creative-result is $0.001 per emitted current creative row. The separate apify-actor-start event is $0.00005 per GB of configured memory at run start. Historical not_observed diff rows are included for comparison but do not trigger another creative-result event. Actual charges shown by Apify depend on configured memory, emitted rows, run settings, and applicable platform usage; these event prices are not a total-cost, revenue, or payout estimate.
Limitations
- Uses public Google Ads Transparency Center surfaces; it is not an official Google Ads API replacement.
- Google can change public RPC schemas or throttle unauthenticated access.
- Advertiser discovery is best-effort. Verify discovered advertiser IDs before using them for critical monitoring.
- CTA, ad text, and landing URL extraction are best-effort only and not guaranteed for every creative.
- Static image creatives often expose media URLs but not text without OCR; OCR is outside this MVP.
- The Actor parses public preview scripts but does not click or follow ad tracking links.
- It does not provide spend, targeting, conversion, impression, or final redirect metrics.
Recommended schedule pattern
- Run once with your competitor domains, region, and a stable
monitorId. - Create an Apify schedule with the same
monitorId, domains, and region. - Leave
autoDiff=trueso each later run compares against the last saved dataset automatically. - Review the
REPORTartifact and datasetchange_statusvalues after each run. - Use
saveMonitorState=falseonly for experiments you do not want to become the next baseline.