# Google Ads Transparency Center Scraper (Pay-Per-Event) (`prodiger/google-ads-transparency-scraper`) Actor

Monitor who is running what ads on Google. Search the Ads Transparency Center by brand name, advertiser ID, domain, or Transparency Center URL. Returns every creative with format, first/last-shown dates, preview image/video, and — optionally — per-region impression ranges. HTTP-only, no login.

- **URL**: https://apify.com/prodiger/google-ads-transparency-scraper.md
- **Developed by:** [Arnas](https://apify.com/prodiger) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Google Ads Transparency Center Scraper

**Monitor who is running what ads on Google.** This actor scrapes the [Google Ads Transparency Center](https://adstransparency.google.com/) and returns every ad creative an advertiser is disclosing — with format, first/last-shown dates, preview image or video, and optional per-region impression ranges. Give it a **brand name**, an **advertiser ID**, a **domain**, or a **Transparency Center URL** and get clean, structured rows you can download as JSON, CSV, Excel, or HTML — or pull straight from the Apify API.

It runs on Apify, so you get scheduling, a REST API, webhooks, proxy rotation, and monitoring out of the box. It's **HTTP-only** — no browser, no login — which makes it fast and cheap.

### Why use the Google Ads Transparency Center Scraper?

- **Competitor ad monitoring** — see every ad a rival is running, when it started, and where it's shown.
- **Creative research** — build a swipe file of image, video, and text ads by brand or industry.
- **Brand protection** — catch impersonators and unauthorized resellers advertising on your name or domain.
- **Ad-spend & trend intelligence** — track which advertisers are ramping up, and (for EU/political ads) their disclosed impression ranges and surfaces.
- **Compliance & research** — pull political and issue-ad transparency data at scale.

### How to use the Google Ads Transparency Center Scraper

1. Open the actor and go to the **Input** tab.
2. Add one or more **advertisers** — e.g. `Nike`, `AR01614014350098432001`, `nike.com`, or a full `adstransparency.google.com/advertiser/...` URL.
3. (Optional) Set a **region** (e.g. `US`, `GB`, `DE`) or leave it as `anywhere`, choose an **ad format**, and set **Max ads**.
4. (Optional) Enable **Scrape ad details** for per-region impression ranges and every creative variant.
5. Click **Start**. When the run finishes, open the **Output** tab or download the dataset.

Running by brand name? Check the run's **key-value store** entry `RESOLVED_ADVERTISERS` to see exactly which advertisers your name matched — then pin an exact `AR…` ID for a precise follow-up run.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `advertisers` | array | **Required.** Brand names, advertiser IDs (`AR…`), domains, or Transparency Center URLs — mix freely. |
| `region` | string | ISO-2 country code (`US`, `GB`, `DE`, …) or `anywhere` (default). Applied server-side. |
| `format` | string | `all` (default), `text`, `image`, or `video`. |
| `advertiserMatch` | string | When a name/domain matches many advertisers: `top` (default), `verified`, `exact`, or `all`. |
| `maxAdvertisersPerQuery` | integer | Cap how many advertisers a name/domain fans out to (default `1`). |
| `maxAds` | integer | Total ads across the whole run (default `100`). |
| `maxAdsPerAdvertiser` | integer | Cap per advertiser (default `1000`). |
| `scrapeAdDetails` | boolean | Fetch per-region impressions, dates, surfaces and all variants (default `false`). |
| `runTag` | string | Optional label copied onto every row. |
| `customMapFunction` | string | Optional JS to transform each row before it's saved. |
| `proxyConfiguration` | object | Proxy settings — residential Apify Proxy strongly recommended. |

Example input:

```json
{
  "advertisers": ["Nike", "nike.com", "AR01614014350098432001"],
  "region": "US",
  "format": "video",
  "maxAds": 200,
  "scrapeAdDetails": true,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output

Each row is one ad creative. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
{
  "advertiserId": "AR01614014350098432001",
  "advertiserName": "lululemon athletica canada inc.",
  "advertiserCountry": null,
  "advertiserVerified": false,
  "advertiserUrl": "https://adstransparency.google.com/advertiser/AR01614014350098432001?region=us",
  "creativeId": "CR13154864943608102913",
  "adUrl": "https://adstransparency.google.com/advertiser/AR01614014350098432001/creative/CR13154864943608102913?region=us",
  "format": "image",
  "firstShown": "2024-05-07T22:47:18.000Z",
  "lastShown": "2026-08-20T11:17:06.000Z",
  "imageUrl": "https://tpc.googlesyndication.com/archive/simgad/15535461744911798090",
  "width": 380,
  "height": 429,
  "regionsServedCount": 1,
  "surfaces": ["Search", "Shopping"],
  "impressionsMin": 25000,
  "impressionsMax": 30000,
  "regionStats": [
    {
      "regionCode": "FR",
      "regionName": "France",
      "firstShown": "2024-05-07",
      "lastShown": "2026-08-20",
      "impressionsMin": 25000,
      "impressionsMax": 30000,
      "surfaces": [{ "surface": "Search", "impressionsMin": 25000, "impressionsMax": 30000 }]
    }
  ],
  "query": "AR01614014350098432001",
  "queryType": "id",
  "region": "US",
  "scrapedAt": "2026-08-20T12:00:00.000Z"
}
```

#### Data fields

| Field | Description |
| --- | --- |
| `advertiserId`, `advertiserName` | The advertiser behind the ad. |
| `advertiserCountry`, `advertiserVerified` | Registered country and Google-verified badge (for name queries). |
| `advertiserUrl`, `adUrl` | Public Transparency Center links to the advertiser and the specific ad. |
| `creativeId` | Google's creative identifier. |
| `format`, `formatCode` | `image`, `video`, `text`, or `html5` (plus Google's raw shape code). |
| `firstShown`, `lastShown` | ISO timestamps of the first and most recent time the ad was seen. |
| `imageUrl`, `previewUrl`, `previewHtml`, `width`, `height` | The ad's image asset, the interactive preview (`content.js`) URL, and dimensions. |
| `imageUrls`, `previewUrls`, `variantsCount` | All creative variants (detail mode). |
| `regionsServedCount`, `surfaces` | How many regions the ad ran in, and which Google surfaces (Search, YouTube, Display, Shopping, Maps, Play) — detail mode. |
| `impressionsMin`, `impressionsMax`, `regionStats` | Disclosed impression ranges and per-region breakdown — detail mode (EU/political ads only). |
| `query`, `queryType`, `region`, `scrapedAt`, `runTag` | Provenance for each row. |

### How much does it cost to scrape the Google Ads Transparency Center?

This actor is **pay-per-event** — you pay only for what you extract, with no monthly rental:

- **$0.01** per run start
- **$2.00 per 1,000 ads** ($0.002 each)
- **+ $0.001 per ad** only when **Scrape ad details** is enabled (an enriched ad totals $3.00 / 1,000)

Scraping 1,000 ads costs about **$2.01**; 10,000 ads about **$20.01**. That's competitive with the field and well below the higher-priced Google Ads Transparency scrapers (which run $3–$17 per 1,000 results), while turning off **Scrape ad details** keeps every run at the base rate.

### Tips and advanced options

- **Ambiguous names** fan out to many advertisers. Keep `maxAdvertisersPerQuery` at `1` (default) for the single best match, use `advertiserMatch: "verified"` or `"exact"` to tighten it, or pin an exact `AR…` ID from the `RESOLVED_ADVERTISERS` audit for deterministic runs.
- **Domain queries** return ads across *every* advertiser pointing at that domain — great for catching resellers.
- **Format filtering** happens client-side so it covers the full ad history (Google's own filter only reaches back to Sept 2023).
- Leave **Scrape ad details** off for the cheapest, fastest runs; turn it on when you need impression ranges, per-region breakdowns, or every variant.
- Use a **residential proxy** — Google throttles datacenter IPs aggressively.

### FAQ, disclaimers, and support

**Is this legal?** The Google Ads Transparency Center is public data that Google itself publishes for transparency. This actor only reads what any visitor can see; it uses no login and collects no private data. You are responsible for complying with Google's Terms of Service and applicable law in your jurisdiction.

**Why are impression numbers empty for my ads?** Google discloses impression ranges and per-surface breakdowns only for **EU** and **political/issue** ads (a DSA requirement). For ordinary commercial ads outside the EU, `impressionsMin/Max` are `null` while dates, format, and creatives are still returned.

**Why can't I get the landing/destination URL or a downloadable video file?** The Transparency Center's data API does not expose the click-through URL or a durable video file — only a renderable preview (`previewUrl`). Open `adUrl` to view the full ad.

**How far back does the data go?** Google retains most Transparency Center ads for about 12 months.

Found a bug or need a field we don't expose yet? Open an issue on the actor's **Issues** tab — custom tweaks are welcome.

# Actor input Schema

## `advertisers` (type: `array`):

One or more advertisers. Each item can be:

- A brand / company name, e.g. `Nike`, `Lululemon` (resolved to advertiser IDs via search)
- An advertiser ID, e.g. `AR01614014350098432001` (used directly, no lookup)
- A domain, e.g. `nike.com`
- A full Transparency Center URL, e.g. `https://adstransparency.google.com/advertiser/AR01614014350098432001?region=US`

## `region` (type: `string`):

Two-letter ISO country code (e.g. `US`, `GB`, `DE`, `FR`, `IN`) to restrict ads to those served in that country, or `anywhere` for all regions. Applied server-side.

## `format` (type: `string`):

Only keep creatives of this format. `All` emits every ad (text, image, and video).

## `advertiserMatch` (type: `string`):

When an advertiser is given by name or domain (not a direct `AR…` ID), several advertisers can match. This chooses which:

- **Top match** — the single best match (default)
- **Verified only** — the top match that carries Google's verified badge
- **Exact name** — only advertisers whose name equals the query exactly
- **All matches** — every candidate, up to the limit below

## `maxAdvertisersPerQuery` (type: `integer`):

Cap how many advertisers a single name/domain query fans out to. Keeps an ambiguous name like `Nike` from scraping dozens of unrelated advertisers. Ignored for direct `AR…` IDs.

## `maxAds` (type: `integer`):

Stop the run after this many ads have been written across all advertisers. Defaults to 100 when left empty (a safety cap — every ad is billed). Raise it deliberately for larger runs; the per-advertiser cap still applies.

## `maxAdsPerAdvertiser` (type: `integer`):

Cap ads collected per advertiser. Google itself stops disclosing at a few thousand per advertiser.

## `scrapeAdDetails` (type: `boolean`):

Fetch one extra lookup per ad for per-region impression ranges, first/last-shown dates per region, and every creative variant. Slower and adds a small per-ad charge. Note: impression numbers are disclosed by Google only for EU and political/issue ads.

## `maxRequestRetries` (type: `integer`):

How many times to retry a failed Transparency Center request (each retry rotates the proxy IP).

## `runTag` (type: `string`):

Optional label written into every output row's `runTag` field — handy when joining datasets later.

## `customMapFunction` (type: `string`):

Optional JavaScript applied to every output row before it is saved. Receives `item` and returns the transformed object. Example: `({ ...item, brand: item.advertiserName?.toUpperCase() })`.

## `proxyConfiguration` (type: `object`):

Proxy settings. Google throttles datacenter IPs aggressively; the default Apify Proxy with residential IPs is strongly recommended.

## Actor input object example

```json
{
  "advertisers": [
    "Nike"
  ],
  "region": "anywhere",
  "format": "all",
  "advertiserMatch": "top",
  "maxAdvertisersPerQuery": 1,
  "maxAds": 100,
  "maxAdsPerAdvertiser": 1000,
  "scrapeAdDetails": false,
  "maxRequestRetries": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Scraped Google ads — one row per creative.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "advertisers": [
        "Nike"
    ],
    "region": "anywhere",
    "format": "all",
    "advertiserMatch": "top",
    "maxAds": 100,
    "customMapFunction": "",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("prodiger/google-ads-transparency-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "advertisers": ["Nike"],
    "region": "anywhere",
    "format": "all",
    "advertiserMatch": "top",
    "maxAds": 100,
    "customMapFunction": "",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("prodiger/google-ads-transparency-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "advertisers": [
    "Nike"
  ],
  "region": "anywhere",
  "format": "all",
  "advertiserMatch": "top",
  "maxAds": 100,
  "customMapFunction": "",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call prodiger/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,prodiger/google-ads-transparency-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/7aLB0y6a09vFCit77/builds/CaOIwKytp0CsDMDMg/openapi.json
