Google Ads Transparency Center Scraper: Google Ads Archive
Pricing
from $0.26 / 1,000 results
Google Ads Transparency Center Scraper: Google Ads Archive
Google Ads Transparency Center scraper: export advertiser ad records for competitor research - creative format, available images, first and last shown dates, and source links. Select advertisers and a region; export JSON, CSV or Excel.
Pricing
from $0.26 / 1,000 results
Rating
0.0
(0)
Developer
Eli J
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
18 hours ago
Last modified
Categories
Share
What Google Ads Archive: Ads Transparency Export does
This Google Ads Transparency Center scraper exports an advertiser's ads from Google's own Ads Transparency Center — text, image and video creatives — as clean JSON, CSV or Excel. It reads the Center over plain HTTP without a browser and takes no Google API key; calling the Actor through the Apify API still authenticates with your Apify API token.
What you get
One row per ad creative: Google's own format for it, the image and its pixel size where the creative has one, the dates Google reports it was first and last shown, and a link back to the ad on Google so anything can be checked at source.
By default a run collects up to 100 ads per advertiser. Raising
maxAdsPerAdvertiser, or setting it to 0, lifts only that cap: maxItems,
the maxRunSeconds budget, the partial stops listed under Output and the ads
Google still retains still limit the rows.
Competitor ad research and creative tracking
firstShown and lastShown are the UTC dates of the first and last shown
instants Google returned when the run read the creative, so they give each
collected creative's shown span, not its serving status. A recent lastShown
does not prove the ad is still shown, and an older one does not prove it
stopped. With the add-on, shownWithinWindow counts rows last shown within
activeWithinDays days of the summary's scrapedAt (see Output).
Ads differ by region: an advertiser with ads in the US may have none in DE. Set Region per market.
How to export Google Ads Transparency data
- Put one or more advertiser names, or Google advertiser ids starting with
AR, inadvertisers. - Choose the
region. - Bound the run with
maxAdsPerAdvertiser,maxItemsandmaxRunSeconds, and leaveproxyConfigurationon. - Optionally turn on
includeRotationSummaryand setactiveWithinDays. - Start the run and export the dataset as JSON, CSV or Excel.
- Check the
ERRORSrecord, theROTATION_SUMMARYrecord when the add-on is on, and the log for other advertiser matches.
Two published tasks show this with Nike, Inc.:
- Export Nike's ads from the Google Ads Transparency Center runs Google Ads Archive for Nike, Inc. in the United States and returns up to 50 of its ads. It runs the saved input shown under Input.
- Summarize Nike Google ad creative rotation
exports up to 20 Nike ads in the US plus an opt-in
ROTATION_SUMMARYrecord. It runs the saved input shown under Input.
Pricing
How much does it cost to export Google Ads Transparency data?
This Actor charges three events. Result is one ad creative written to the
dataset. Creative rotation summary (add-on) is charged only when
includeRotationSummary is on, subject to the charge, write, skip and error
rules below. Actor Start is charged when the Actor starts running: one
event per GB of Actor memory, minimum one. The unit prices you pay depend on
your subscription plan; see the rates on the
current Pricing tab.
Result rows and an automatic, memory-scaled Actor Start event are charged
separately. No result charge without result rows. The automatic Actor Start
event still applies; an empty or failed run is not promised to be free. Failed
requests are never written to the dataset, so you are not charged a result row
for this Actor's errors. The creative-rotation summary lives in the run's
key-value store, not the dataset, and is charged once per summarized advertiser
only when includeRotationSummary is on and at least one collected row for that
advertiser carries both firstShownTimestamp and lastShownTimestamp. If the
record write fails after the charge, ERRORS says so under rotationSummaryWrite.
A spending-limit skip is recorded there under rotationSummarySkipped. A skip is
recorded under rotationSummaryUnknown when charged_count was unavailable and
event_charge_limit_reached was true, or was zero without
event_charge_limit_reached.
Passing the same advertiser twice — by name and by id, say — collects it once, so a duplicated list does not become a duplicated invoice.
A run whose advertisers exist but have no ads in that region finishes successfully with an empty dataset and an explanation in the log. So does a run where a name matches nothing: that is an answer, not a failure. A run fails when an input is invalid, or when every advertiser was actually unreadable, with the reason in the status message.
maxAdsPerAdvertiser caps each advertiser's result rows and so their result
charges; maxItems caps the whole run's rows. The Actor Start event and, when
includeRotationSummary is on, the per-advertiser summary event are charged
separately.
Input
| Field | Type | Default | Description |
|---|---|---|---|
advertisers | array | — | Advertiser names (Nike, Inc.) or Google advertiser ids (AR16735076323512287233). Required — with none set the run stops without writing result rows, and the Actor Start event can still be charged. |
region | string | US | US, GB, DE, IN, CA, AU or JP. For any other country pass Google's numeric region code (2000 + the ISO-3166-1 numeric country code). |
maxAdsPerAdvertiser | integer | 100 | Stop after this many ads per advertiser. This caps each advertiser's result rows and so their result charges. 0 means no limit. |
maxItems | integer | 0 | Stop the whole run after this many rows. 0 means no limit. |
maxRunSeconds | integer | 900 | Stop starting new pages after this many seconds. 0 disables the budget. |
maxRetriesPerRequest | integer | 8 | Retries when Google rate-limits a request; each one backs off and rotates the proxy IP. |
rotateAfterRequests | integer | 24 | Retire a proxy identity after this many requests. 0 disables proactive rotation. |
proxyConfiguration | object | Apify Proxy | Google rate-limits a single address with 429 during sustained reading, so leaving the proxy on is strongly recommended. |
includeRotationSummary | boolean | false | Opt-in add-on. When on, the run writes one per-advertiser creative-rotation summary to the ROTATION_SUMMARY key-value record (never the dataset) and charges the custom event advertiser-rotation-summary once per summarized advertiser that has at least one collected row carrying both firstShownTimestamp and lastShownTimestamp, then writes the record; a write that fails after the charge is reported under rotationSummaryWrite in ERRORS, a spending-limit skip under rotationSummarySkipped, and a skip under rotationSummaryUnknown when charged_count was unavailable and event_charge_limit_reached was true, or was zero without event_charge_limit_reached. coverage is complete only when Google returned no further page; the output table's stopReason row lists the six partial reasons (maxAdsPerAdvertiser, maxItems, maxRunSeconds, duplicatePage, repeatedToken, emptyPage). Off: no summary and no add-on charge. |
activeWithinDays | integer | 7 | Look-back window in whole days from the instant this run started collecting (scrapedAt, shared by every advertiser so summaries are comparable). shownWithinWindow counts collected creatives whose lastShownTimestamp falls in that window, inclusive of the exact boundary. Minimum 1. coverage is complete only when Google returned no further page; the output table's stopReason row lists the six partial reasons (maxAdsPerAdvertiser, maxItems, maxRunSeconds, duplicatePage, repeatedToken, emptyPage). |
Advertiser names and ids
Put one or more advertiser names in Advertisers and run it. A name is
resolved against Google's own advertiser directory and the closest match is
used; when a brand has several registered entities the alternatives are listed
in the log so you can switch to an exact id. To pin an exact advertiser, pass
its Google id, such as AR16735076323512287233, instead of a name.
Saved inputs of the published tasks
Export Nike's ads from the Google Ads Transparency Center
{"advertisers": ["Nike, Inc."],"region": "US","maxAdsPerAdvertiser": 50,"maxItems": 0,"maxRunSeconds": 900,"maxRetriesPerRequest": 8,"rotateAfterRequests": 24,"proxyConfiguration": {"useApifyProxy": true}}
Summarize Nike Google ad creative rotation
{"advertisers": ["Nike, Inc."],"region": "US","maxAdsPerAdvertiser": 20,"includeRotationSummary": true,"activeWithinDays": 30,"maxItems": 0,"maxRunSeconds": 900,"maxRetriesPerRequest": 8,"rotateAfterRequests": 24,"proxyConfiguration": {"useApifyProxy": true}}
Output
{"advertiserId": "AR16735076323512287233","advertiserName": "Nike, Inc.","creativeId": "CR05576182909712203777","format": "text","formatCode": 1,"imageUrl": "https://tpc.googlesyndication.com/archive/simgad/10891172661046192318","imageWidth": 348,"imageHeight": 174,"previewUrl": null,"firstShown": "2022-11-30","lastShown": "2026-07-27","firstShownTimestamp": 1669820166,"lastShownTimestamp": 1785116984,"region": "US","regionCode": 2840,"creativeUrl": "https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR05576182909712203777?region=US","scrapedAt": "2026-07-27T01:10:00+00:00"}
That row is a real one, taken verbatim from a live run. Note it: a text ad
that carries an image. That is normal, and it is why you should filter on
format rather than on whether imageUrl is set.
format is Google's own classification, read from the format code it
returns, not inferred from what the creative happens to contain:
formatCode | format |
|---|---|
1 | text |
2 | image |
3 | video |
Anything else is reported as other with the raw formatCode kept, so a new
Google format arrives visible rather than silently mislabelled. Do not infer the
format from whether a row has an image: text ads carry images too, so
filtering on imageUrl returns search ads alongside display ones.
Dates. firstShown and lastShown are the UTC date of the instants Google
returns. Those instants are not midnight boundaries, so a reader in another
timezone may want a different calendar date — firstShownTimestamp and
lastShownTimestamp carry the raw epoch seconds for exactly that.
previewUrl is Google's own preview endpoint for the creative. It is a
script payload meant to be embedded by Google's viewer rather than a standalone
page, so treat it as an identifier for the creative rather than a link to hand
to a browser. imageUrl and creativeUrl are ordinary URLs.
Key-value store. Failed requests are recorded on the ERRORS key, never as
dataset rows. When includeRotationSummary is on, ROTATION_SUMMARY is a JSON
list with one object per summarized advertiser. Those objects are not dataset
rows and are not billed as results. Each object carries:
| Field | Definition |
|---|---|
advertiserId | Resolved Google advertiser id for this object. |
advertiserName | Display name Google returned for that id. |
creativesCollected | Count of creative rows collected for this advertiser in this run. |
byFormat | Count of those rows per Google format (text / image / video / other). |
earliestFirstShown | UTC date of the smallest firstShownTimestamp among rows that have one. |
latestLastShown | UTC date of the largest lastShownTimestamp among rows that have one. |
medianRunDays | Median of (lastShownTimestamp - firstShownTimestamp) / 86400 over rows that have both timestamps. An even count uses the average of the two middle values. |
longestRunningCreative | {id, days} for the row with the largest (lastShownTimestamp - firstShownTimestamp) / 86400; a tie goes to the lexicographically smaller creativeId. |
shownWithinWindow | Count of rows whose lastShownTimestamp is within activeWithinDays days of this run's scrapedAt, inclusive of the exact boundary (lastShownTimestamp >= scrapedAt minus windowDays). Not a count of "active ads" except under that window. |
windowDays | The activeWithinDays value used for shownWithinWindow. |
scrapedAt | The instant this run started collecting, as UTC ISO-8601 with seconds, shared by every advertiser in the run so summaries are comparable. The window cutoff is measured from that instant. |
coverage | complete only when this advertiser's walk ended because Google returned no further page; otherwise partial (including a duplicatePage, repeatedToken, or emptyPage stop). |
stopReason | Present when coverage is partial: maxAdsPerAdvertiser, maxItems, maxRunSeconds, chargeLimit (the maximum cost you set for the run was reached), duplicatePage (a page held only already-collected creatives), repeatedToken (Google repeated a pagination token), or emptyPage (an empty page that still carried a next token). |
rowsWithoutDates | Count of collected rows missing a usable firstShownTimestamp or lastShownTimestamp. These rows are excluded from medianRunDays and longestRunningCreative; an available first or last timestamp still contributes to earliestFirstShown or latestLastShown, respectively, and an available last timestamp can count toward shownWithinWindow. |
ERRORS is a JSON list of handled failures. Each object names the input
advertiser and one of notFound, error, rotationSummaryCharge (the
add-on charge raised; base rows for that advertiser were still delivered),
rotationSummarySkipped (the spending limit was reached before this summary
could be charged; base rows were still delivered), rotationSummaryUnknown
(charged_count was unavailable and event_charge_limit_reached was true,
or charged_count was 0 and event_charge_limit_reached was not reported;
the summary was not written and base rows were still delivered) or
rotationSummaryWrite (the summary was charged but its record write failed;
base rows were still delivered).
Related Actors
| Actor | Research fit | What it exports |
|---|---|---|
| Kalshi Weather Price History | Weather-market price history | Hourly or daily candles for named Kalshi weather markets: prices, bids, asks, volume and open interest as exact decimal strings |
| UFCStats Fight & Round Stats | UFC fight statistics | UFCStats fight and round statistics as flat rows with fighter IDs, event dates and locations |
| Tennis Abstract Data API | Tennis match statistics | ATP and WTA player match histories from Tennis Abstract: scores, opponents, surfaces and available serve and return statistics |
| Google Trends Data API | Search-interest research | Google Trends interest over time, interest by region and related or rising queries, plus the Trending Now board by country |
| Clutch Scraper: Agency Directory | Agency research and lead generation | B2B agency listings from Clutch.co directories: company names, websites, locations, headcounts and service mix |
FAQ and support
How do I export an advertiser's ads from the Google Ads Transparency Center?
Put the advertiser's name or Google id in advertisers, choose the region,
and set maxAdsPerAdvertiser (see Input). Then export the run's dataset as
JSON, CSV or Excel. The
Export Nike's ads from the Google Ads Transparency Center
task shows one such input.
How do I summarize an advertiser's Google ad creative rotation?
Turn on includeRotationSummary. The summary is a ROTATION_SUMMARY
key-value record, not dataset rows, and it is charged once per summarized
advertiser under the rules in Pricing. Each summary covers only the rows
collected for that advertiser in that run, so a walk stopped by
maxAdsPerAdvertiser has coverage partial with that stopReason (see
Output). The
Summarize Nike Google ad creative rotation
task shows the add-on turned on.
Do first and last shown dates show that an ad is still running?
No. firstShown and lastShown are the UTC dates of the first and last shown
instants Google returned when the run read the creative, so they give each
collected creative's shown span, not its serving status. A recent lastShown
does not prove the ad is still shown, and an older one does not prove it
stopped. With the add-on, shownWithinWindow counts rows last shown within
activeWithinDays days of the summary's scrapedAt. This Actor cannot show
ads Google has removed.
How do I pick the exact advertiser?
A name is resolved to the closest match, and up to three other matches are
listed in the log. To pick precisely, pass the advertiser's Google id instead.
A name or id Google does not list is recorded as notFound in ERRORS, not as
a failed run. One advertiser reached by both name and id is collected once.
Do I need a Google API key?
No. This Actor takes no Google API key. Calls to the Actor through the Apify API use your Apify API token.
Why did I get fewer ads than expected?
maxAdsPerAdvertiserstops each advertiser at 100 ads by default.maxItemsstops the whole run after that many rows.maxRunSecondsstops new pages and new advertisers once the budget is spent.- A maximum cost you set for the run does the same once it is reached: the run stores no further rows, reads no further pages or advertisers, ends normally, and the log says how many ads were delivered.
- A walk can stop early on
duplicatePage,repeatedTokenoremptyPage(see Output). - Ads differ by region, so an advertiser may have fewer or no ads in the
regionyou chose. - A name or id Google does not list is recorded as
notFoundinERRORS. - An advertiser whose ads could not be read is recorded under
errorinERRORS. - Only ads Google still retains are listed.
- When every advertiser was unreadable, the run fails with the reason in the status message.
Notes and limits
- Only advertisers Google has verified appear in the Transparency Center, and only ads Google still retains are listed. This Actor reports what that archive contains; it cannot show ads Google has removed.
- An advertiser must be specified. This Actor has no all-advertisers or category mode, so it cannot sweep a whole category in one run.
- Ad counts, spend and impression ranges shown for political ads in some regions are not included — this Actor returns creatives.
Support
For bugs or questions, open an issue on the Issues tab of this Actor's page.