Google Ads Library Scraper avatar

Google Ads Library Scraper

Pricing

from $2.00 / 1,000 results

Go to Apify Store
Google Ads Library Scraper

Google Ads Library Scraper

Scrapes ads from the Google Ads Transparency Center. Returns creative content, advertiser info, ad format, dates, and asset URLs.

Pricing

from $2.00 / 1,000 results

Rating

2.4

(4)

Developer

Practical Tools

Practical Tools

Maintained by Community

Actor stats

0

Bookmarked

25

Total users

5

Monthly active users

14 days ago

Last modified

Share

Google Ads Transparency Center Scraper

Scrapes ads from the Google Ads. Returns creative content, advertiser info, ad format, dates, and asset URLs.

Features

  • No login required — Google's Transparency Center is publicly accessible
  • Search by website or advertisernike.com searches a website, Nike resolves to matching advertisers automatically
  • Filter by region — 65+ countries supported
  • Filter by platform — Search, YouTube, Play, Maps, Shopping
  • Filter by format — text, image, video ads
  • Date range filtering — custom date range or preset timeframes
  • No browser needed — pure HTTP API calls with undici, fast and lightweight

How It Works

The actor reverse-engineers Google's internal "anji" RPC API that powers the Transparency Center frontend. It:

  1. Establishes session cookies via a simple HTTP GET (no Playwright/browser required)
  2. Resolves an advertiser-name query to advertiser IDs via SearchService/SearchSuggestions (skipped when the query is a domain)
  3. Searches for creatives using SearchService/SearchCreatives
  4. Optionally fetches per-ad detail via LookupService/GetCreativeById
  5. Normalizes the proto-JSON response into clean JSON output

Search scopes

Google's Transparency Center supports exactly two scopes, and there is no browse-everything mode — a query is always required:

QueryScopeHow it works
nike.comWebsiteSent as a domain filter
NikeAdvertiserResolved to advertiser IDs, ranked by exact match → Google's verified flag → ad volume

With queryType: "auto" (the default), a domain-shaped query is tried as a website and anything else as an advertiser name; if the first scope finds nothing, the other is tried automatically.

Input

FieldTypeDescriptionDefault
querystringRequired. Website (nike.com) or advertiser name (Nike) to look up ads for.
queryTypeselectHow to read the query: auto, domain, or advertiser.auto
maxAdvertisersintegerFor advertiser-name queries, how many matching advertisers to pull ads from.10
regionselectCountry to filter ads by.anywhere
platformselectPlatform filter: all, search, youtube, play, maps, shopping.all
creativeFormatselectAd format: all, text, image, video.all
dateStartstringStart date in YYYY-MM-DD format (optional).(empty)
dateEndstringEnd date in YYYY-MM-DD format (optional).(empty)
timeframeselectPreset date range (used when dateStart/dateEnd not set).365d
limitintegerMaximum number of ads to collect (up to 100 per page).20
scrapeAdDetailsbooleanFetch full ad detail for each result (format, assets, dates).true
proxyConfigurationobjectStandard Apify proxy configuration.{ useApifyProxy: true }

Output

Each ad in the dataset has this structure:

{
"id": "CR14652493479645544449",
"advertiserId": "AR18378488041124659201",
"advertiserName": "Nike Retail BV",
"domain": "nike.com",
"adFormat": "image",
"firstShownDate": 1677628800,
"lastShownDate": 1787567197,
"totalDaysShown": 1256,
"category": "Apparel & Accessories",
"categoryId": 166,
"impressions": { "min": 3000000, "max": 3500000 },
"platforms": [
{ "platform": "search", "impressionsMin": 2500000, "impressionsMax": 3000000 },
{ "platform": "shopping", "impressionsMin": 60000, "impressionsMax": 70000 }
],
"regions": [
{
"code": "CZ",
"regionId": 2203,
"impressionsMin": 3000000,
"impressionsMax": 3500000,
"firstShown": "2023-03-01",
"lastShown": "2026-08-24",
"platforms": [{ "platform": "search", "impressionsMin": 2500000, "impressionsMax": 3000000 }]
}
],
"assets": {
"images": [
{ "url": "https://tpc.googlesyndication.com/archive/simgad/104202098", "width": 380, "height": 503 }
],
"videos": [],
"previews": [
{
"url": "https://displayads-formats.googleusercontent.com/ads/preview/content.js?...",
"width": null,
"height": null
}
]
},
"detail": null
}

assets is split by what each URL actually is:

  • images / videos — directly downloadable media files
  • previewscontent.js ad-preview endpoints. These are JavaScript, not media: load them in an iframe, don't fetch them as files.

scrapeAdDetails is on by default. The search response alone carries only a sparse subset of a creative's assets; the detail endpoint returns roughly 2.5x as many downloadable images. The cost is one extra request per ad, so a 20-ad run makes 21 requests instead of 1 — turn it off for fast, cheap listings, or when Google is rate limiting you.

Reach data

category, impressions, platforms and regions come from the detail endpoint and require scrapeAdDetails: true (the default). Google reports impressions as a range, never an exact number, and omits the lower bound for low-volume regions — so min can be null while max is set.

category is localized by Google to the IP the run executes from — the same ad returns "Apparel & Accessories" from a US proxy and "לבוש ואביזרים" from an Israeli one. Key off categoryId (stable numeric) if you need to group or filter reliably.

Not available: the detail response contains no landing-page URL, so there is no landingPage field. For image/display creatives Google also returns no downloadable image — only a previews embed — so assets.images is legitimately empty for many ads.

Example Inputs

Search for Tesla ads in the US:

{
"query": "tesla.com",
"region": "US",
"limit": 50,
"scrapeAdDetails": true
}

Search by advertiser name rather than domain:

{
"query": "Nike",
"queryType": "advertiser",
"maxAdvertisers": 1,
"limit": 50
}

All video ads a brand ran on YouTube:

{
"query": "Coca-Cola",
"creativeFormat": "video",
"platform": "youtube",
"timeframe": "90d",
"limit": 20,
"scrapeAdDetails": false
}

Search with custom date range:

{
"query": "amazon.com",
"region": "anywhere",
"dateStart": "2024-01-01",
"dateEnd": "2024-06-30",
"limit": 100
}

Proxy and rate limiting

On the Apify platform, the actor uses Apify Proxy automatically. Configure proxyConfiguration to use residential proxies or custom proxy URLs.

Google rate limits the Transparency Center per IP and answers with HTTP 429. The actor retries with exponential backoff and fails loudly if the limit does not clear — it will not report a throttled run as "no ads found". If you hit 429s repeatedly, switch proxyConfiguration to residential proxy groups.