Google Ads Archive: Ads Transparency Export avatar

Google Ads Archive: Ads Transparency Export

Pricing

from $0.26 / 1,000 results

Go to Apify Store
Google Ads Archive: Ads Transparency Export

Google Ads Archive: Ads Transparency Export

Export every ad an advertiser runs on Google, from the official Ads Transparency Center: creative image, first and last shown dates, format, and a link to the ad on Google. Any country, no API key.

Pricing

from $0.26 / 1,000 results

Rating

0.0

(0)

Developer

Eli J

Eli J

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a few seconds ago

Last modified

Categories

Share

Google Ads Archive

Export an advertiser's ads from Google's own Ads Transparency Center — text, image and video creatives — as clean JSON, CSV or Excel. No API key, no browser, no scraping code.

Google publishes this archive but gives it no API and no export button. This Actor turns it into a table.

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 it first and last ran, 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 — large brands run thousands, so raise maxAdsPerAdvertiser (or set it to 0) when you want the full history, and watch the cost.

How to scrape Google ads by advertiser

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.

{
"advertisers": ["Nike, Inc."],
"region": "US",
"maxAdsPerAdvertiser": 100
}

To pin an exact advertiser, pass its Google id instead:

{
"advertisers": ["AR16735076323512287233"],
"region": "GB"
}

Competitor ad research and creative tracking

Because every row carries firstShown and lastShown, a single run tells you which creatives a competitor is still running, which they retired, and how long each has been live. Re-run it on a schedule and the diff is a creative-rotation timeline.

Ads differ by country: an advertiser with thousands of ads in the US may have none in Germany. Set Region per market.

Input

FieldTypeDefaultDescription
advertisersarrayAdvertiser names (Nike, Inc.) or Google advertiser ids (AR16735076323512287233). Required — with none set the run stops and charges nothing.
regionstringUSUS, 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).
maxAdsPerAdvertiserinteger100Stop after this many ads per advertiser. A large advertiser can run thousands — Google reports 9,000-10,000 for Nike in the US alone — so this is the main cost control. 0 means no limit.
maxItemsinteger0Stop the whole run after this many rows. 0 means no limit.
maxRunSecondsinteger900Stop starting new pages after this many seconds. 0 disables the budget.
maxRetriesPerRequestinteger8Retries when Google rate-limits a request; each one backs off and rotates the proxy IP.
rotateAfterRequestsinteger24Retire a proxy identity after this many requests, before Google throttles it. 0 disables proactive rotation.
proxyConfigurationobjectApify ProxyGoogle rate-limits a single address with 429 during sustained reading, so leaving the proxy on is strongly recommended.
includeRotationSummarybooleanfalseOpt-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.
activeWithinDaysinteger7Look-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).

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:

formatCodeformat
1text
2image
3video

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:

FieldDefinition
advertiserIdResolved Google advertiser id for this object.
advertiserNameDisplay name Google returned for that id.
creativesCollectedCount of creative rows collected for this advertiser in this run.
byFormatCount of those rows per Google format (text / image / video / other).
earliestFirstShownUTC date of the smallest firstShownTimestamp among rows that have one.
latestLastShownUTC date of the largest lastShownTimestamp among rows that have one.
medianRunDaysMedian 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.
shownWithinWindowCount 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.
windowDaysThe activeWithinDays value used for shownWithinWindow.
scrapedAtThe 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.
coveragecomplete only when this advertiser's walk ended because Google returned no further page; otherwise partial (including a duplicatePage, repeatedToken, or emptyPage stop).
stopReasonPresent when coverage is partial: maxAdsPerAdvertiser, maxItems, maxRunSeconds, 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).
rowsWithoutDatesCount of collected rows missing firstShownTimestamp or lastShownTimestamp. Those rows are excluded from the date arithmetic above.

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).

Cost

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 only when every advertiser was actually unreadable, with the reason in the status message.

Set maxAdsPerAdvertiser to bound a run before you start it — that is the field that decides what a large advertiser costs.

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. Google's archive has no "all advertisers" view, so there is no way to sweep a whole category in one call.
  • Ad counts, spend and impression ranges shown for political ads in some regions are not included — this Actor returns creatives.