Google Ads Transparency Center Scraper (Advertisers & Ads) avatar

Google Ads Transparency Center Scraper (Advertisers & Ads)

Pricing

from $0.80 / 1,000 ads

Go to Apify Store
Google Ads Transparency Center Scraper (Advertisers & Ads)

Google Ads Transparency Center Scraper (Advertisers & Ads)

Scrape Google Ads Transparency Center: find advertisers by name or ID and export their ads with format, first and last shown dates, preview and ad links, filtered by region. No browser. $0.80 per 1,000 ads, $0.50 per 1,000 advertisers.

Pricing

from $0.80 / 1,000 ads

Rating

0.0

(0)

Developer

subimpact

subimpact

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

11 hours ago

Last modified

Share

Scrape Google's public Ads Transparency Center (adstransparency.google.com) for advertisers and their ads. Search advertisers by name or domain, or pass AR... advertiser ids directly, then get one row per creative with its format, preview link, public ad permalink, first and last shown dates, and the region you asked for.

Pure HTTP against the site's own JSON RPC. No browser, no Playwright, no login, no Google API key. Requests run through the Apify proxy because Google answers direct requests from datacenter IPs with HTTP 429.

Input

FieldTypeDefaultNotes
searchTermsarray of stringsnone (prefill ["adidas"])Advertiser names or domains. Each term is resolved to advertisers first
advertiserIdsarray of stringsnoneAR... ids, used directly and skipping the search
regionstringanywhereTwo letter ISO code such as US, GB, MY, SG, TH, or anywhere
maxAdsPerAdvertiserinteger401 to 1000. The form default is 40; an empty API input ({}) uses 10
maxAdvertisersPerTerminteger31 to 20, in the order Google returns them
maxItemsinteger100Global cap on ad rows for the whole run, 1 to 5000
concurrencyinteger5Parallel advertisers, 1 to 20. Each one gets its own proxy session
proxyConfigurationobject{"useApifyProxy": true}Required, see the proxy note below

At least one of searchTerms or advertiserIds must be non-empty. Invalid values (an advertiser id that is not AR followed by letters and digits, a region Google has no geo id for, a cap of 0) fail the run immediately with a clear message, before any request and before any charge.

Example inputs

Pre-filled example, one advertiser with 20 ads, region not filtered:

{
"searchTerms": ["adidas"],
"maxAdvertisersPerTerm": 1,
"maxAdsPerAdvertiser": 20
}

An empty input works too. {} is treated as adidas, 10 ads per advertiser, at most 3 advertisers and 100 ads in total:

{}

By advertiser id, filtered to Thailand, up to 40 ads:

{
"advertiserIds": ["AR17365672681860497409"],
"region": "TH",
"maxAdsPerAdvertiser": 40
}

A domain instead of a name:

{
"searchTerms": ["adidas.com"],
"maxAdvertisersPerTerm": 2,
"maxAdsPerAdvertiser": 15
}

Google's suggestion endpoint answers a domain query with domain entries that carry no advertiser id, so the Actor retries such a term with the domain's name part (adidas.com becomes adidas) and logs that it did so. If you already know the advertiser, advertiserIds is exact and skips this round trip.

Output

One row per ad plus one row per matched advertiser. rowType tells them apart: ad, advertiser or error. Error rows are informational and are never charged.

FieldTypeOnNotes
rowTypestringallad, advertiser or error
advertiserIdstring or nullallAR... id
advertiserNamestring or nullad, advertiserName as Google publishes it
countrystring or nulladvertiserCountry code on the matching suggestion
adCountEstimateinteger or nulladvertiserUpper bound of Google's ad count range
verifiedboolean or nulladvertiserGoogle's verification flag, null when the payload omits it
creativeIdstring or nulladCR... id
adFormatstring or nulladtext, image, video or unknown
previewUrlstring or nulladGoogle hosted preview, either an image or a content.js renderer
adUrlstring or nulladPublic Ads Transparency Center permalink
firstShownstring or nulladISO 8601 timestamp
lastShownstring or nulladISO 8601 timestamp
regionQueriedstring or nulladThe region used for the search, or anywhere
searchTermstring or nullallTerm that produced the advertiser, null for advertiserIds
scrapedAtstringallISO 8601 timestamp of this run
errorstring or nullerrorFailure reason

Real rows, taken from the captured Nike SRL responses in test/fixtures/. The ad row is the first creative in that response:

{
"rowType": "advertiser",
"advertiserId": "AR17365672681860497409",
"advertiserName": "NIKE SRL",
"country": "IT",
"adCountEstimate": 8,
"verified": null,
"searchTerm": "nike",
"scrapedAt": "2026-10-24T12:00:00.000Z"
}
{
"rowType": "ad",
"advertiserId": "AR17365672681860497409",
"advertiserName": "NIKE SRL",
"creativeId": "CR00017566880097107969",
"adFormat": "text",
"previewUrl": "https://tpc.googlesyndication.com/archive/simgad/5369694199582718379",
"adUrl": "https://adstransparency.google.com/advertiser/AR17365672681860497409/creative/CR00017566880097107969",
"firstShown": "2025-12-05T04:56:43.000Z",
"lastShown": "2025-12-22T22:59:54.000Z",
"regionQueried": "anywhere",
"searchTerm": "nike",
"scrapedAt": "2026-10-24T12:00:00.000Z"
}

The other seven creatives in the same captured response are CR06126911430613532673 (video, shown 2025-11-26 to 2025-12-22), CR02919090104867749889 (image, 2025-12-02 to 2025-12-22), CR13902772011454693377 (text), CR08131215574932914177 (image), CR03470410798679982081 (video, 2025-10-19 to 2025-11-22), CR10815781378604400641 (image) and CR16552501301028585473 (image). Advertiser rows from the nike suggestion response include Nike, Inc. (AR16735076323512287233, US, estimate 10000) and Nike Srl (AR03550664066492006401, IT, estimate 1).

adFormat comes from the creative's format code, which was verified against the preview payloads:

CodeLabelEvidence in the preview payload
1textoverlay protobuf carries headline, description, visurl
2imageoverlay carries productAdsRenderingData with the product and image data
3videoassets protobuf carries media asset ids
otherunknownlabelled rather than guessed

A text ad still gets an image preview from Google (simgad render), and video ads get a content.js renderer. previewUrl points at whichever form Google returned.

adCountEstimate is the upper bound of the range Google reports. For an advertiser shown as "9000 to 10000 ads" the row carries 10000. verified is true when the suggestion payload carries Google's verification flag and null when the flag is absent, which is the common case.

How it works

Session and proxy

GET https://adstransparency.google.com/?region=XX mints the session cookie (NID on .google.com). Each advertiser then uses its own proxy session and its own cookie jar, so one throttled advertiser cannot poison the others.

The proxy is not optional. On 2026-10-24 every direct request from an Apify container got HTTP 429, while the Apify datacenter proxy (auto group) returned 200 for the homepage, suggestions and creatives, including a 10 way parallel suggestion burst (10/10). If the proxy cannot be created or cannot issue a URL, the Actor fails instead of silently going direct.

POST /anji/_/rpc/SearchService/SearchSuggestions?authuser= with a form encoded body f.req={"1":"<term>","2":10,"3":10}.

The response has one mixed array under "1". Entries shaped {"1":{...}} are advertisers: 1 name, 2 AR... id, 3 country, 4.2.1/4.2.2 ad count range, 5 verification flag. Entries shaped {"2":{"1":"nike.com"}} are domains and carry no advertiser id.

Ads by advertiser

POST /anji/_/rpc/SearchService/SearchCreatives?authuser= with f.req={"2":40,"3":{"12":{"1":"","2":true},"13":{"1":["AR..."]}},"7":{"1":1}}.

Field notes, all verified against live responses:

  • "2" is the page size (40 works and returns 40 distinct creatives).
  • "3"."13"."1" is the advertiser id list.
  • "3"."8" is the region filter, a list of numeric Google Ads geo target ids.
  • "4" at the top level is the next page token, echoed back from the previous response's top level "2". Two consecutive pages of one advertiser contained 40 and 40 creatives with no overlapping ids.
  • Each creative: 1 advertiser id, 2 CR... id, 3 preview block (3.1.4 is the content.js URL, 3.3.2 is an <img> snippet), 4 format code, 6.1 first shown in Unix seconds, 7.1 last shown in Unix seconds, 12 advertiser name.

An empty result set is {}, which is valid and means zero matching creatives. A changed payload (an items array with no usable CR... id, or a non-array where an array belongs) raises a shape error: the run records an uncharged error row instead of delivering hollow rows.

Region filter

The region is translated from the ISO code to Google's Ads geo target id using the country table published in the Google Ads API geo targets CSV (release 2026-10-06, 219 active countries). The table is embedded in src/regions.js and maps, for example, US to 2840, MY to 2458, SG to 2702 and TH to 2764.

This was checked against the live service: the same advertiser returned 8 ads with "8":[2840] (US) and a full 40 of 200 to 300 with "8":[2458] (MY). anywhere sends no "8" filter at all.

Pagination

The Actor follows the top level "2" token as "4" until it has maxAdsPerAdvertiser rows, the token stops changing, a page adds no new creative ids, the global maxItems cap is reached, or 60 pages have been read. Creative ids are deduped per advertiser, so a token that re-serves an item cannot double charge.

Retries and rate limits

Each request has a 30 second timeout. HTTP 429, 5xx and network errors are retried up to 3 times, and every retry opens a fresh proxy session with a new session id and new cookies. A 429 waits 5 to 15 seconds with jitter first. HTTP 400 and 404 are not retried. If all attempts fail, the search term or advertiser produces one error row and the run continues with the rest.

Pay per event

EventPriceCharged when
ad$0.0008 per ad rowImmediately after the row is pushed to the dataset
advertiser$0.0005 per advertiser rowImmediately after the row is pushed to the dataset

Rows are pushed and charged one at a time, so a run that times out still delivers and bills only what it already pushed. Error rows are pushed for diagnostics and are never charged. A failed charge logs a warning and never kills the run. Apify platform usage is paid by you, the buyer, on top of these event prices.

Typical event cost: the pre-filled example (1 advertiser, at most 20 ads) is at most about $0.0165. An empty input ({}, up to 3 advertisers and 30 ads) is at most about $0.026. A run that hits the 100 ad cap is $0.08 in ad rows plus advertiser rows.

How this compares

At $0.80 per 1,000 ads and $0.50 per 1,000 advertisers, this Actor costs about half of the $1.50 actors and less than half of scrapesage's $2.00. Unlike scrapesage, there is no separate "ad details" event: every row already includes the format, the preview URL, the public permalink and both dates.

ActorAds (per 1,000)Other eventsPlatform usage
subimpact/google-ads-transparency-scraper$0.80advertiser rows $0.50 per 1,000paid by you
scrapesage/google-ads-transparency-scraper$2.00ad details $3.00 per 1,000, advertisers $3.00 per 1,000. Listing shows 1,261 users in 30 dayssee listing
solidcode Ads Transparency actorabout $1.50see listingsee listing
s-r Ads Transparency actorabout $1.50see listingsee listing

Prices are Apify Store list prices on the Free plan, checked 24 October 2026. Competitor prices can change; check their listings.

Limits and cost guardrails

  • maxItems defaults to 100 ad rows and can be set from 1 to 5000. It is enforced across all advertisers and all search terms, including the parallel workers.
  • maxAdsPerAdvertiser is 1 to 1000. The form default is 40, an empty API input uses 10.
  • maxAdvertisersPerTerm is 1 to 20. Explicit advertiserIds are all processed.
  • At most 100 advertisers are processed in one run, whatever the input. This keeps a many-term run from turning into hundreds of advertiser rows.
  • concurrency is 1 to 20 and defaults to 5. Higher values finish faster and hit rate limits more often.
  • Only 219 country codes are accepted for region, plus anywhere. The list comes from Google's own geo target table.
  • Ads are returned 40 per request and at most 60 pages per advertiser are read.
  • Preview URLs are Google hosted. A content.js preview is a renderer, not an image file, so it needs a browser to display; an image preview can be opened or downloaded directly.

Responsible use

The Ads Transparency Center is a public archive about advertisers and their creatives. This Actor is meant for competitive research, ad monitoring, brand safety checks and journalism. It does not collect data about ad viewers, log in anywhere, or touch private accounts.

Google still owns the service. Keep request volume modest, do not use the output to target or profile individuals, respect Google's terms and any local rules that apply to political advertising data, and check a sample of rows before you rely on them for a decision.

When Google blocks

If Google rate limits every request, the run retries each request three times on fresh proxy sessions. A term or advertiser that still fails leaves one error row in the dataset and is not charged. A run that delivers no ad and no advertiser row fails with a status message instead of ending as a silent empty success. RUN_SUMMARY in the key-value store records request counts, retries, rate limited responses and the per-run caps.

Development

npm install
npm test

The tests run with node --test and are fully offline: parser, input validation, billing order, budget and proxy helpers are pure functions, and the parser runs against the captured fixtures in test/fixtures/. Captures were taken on 2026-10-24; signed preview URLs had their signature parameters scrubbed. A failing parser test means the code changed or Google changed the payload, not that the network flaked.