# Google Ads Transparency Center Scraper (`clearscrape/google-ads-transparency-scraper`) Actor

Every Google ad a brand or domain runs on Search, YouTube, Shopping, Maps and Play: format, first/last shown, days running, image/preview/YouTube links, plus optional per-country impressions and platform breakdown. Monitor mode for new ads.

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

## Pricing

from $0.90 / 1,000 ad results

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Ads Transparency Center Scraper

See **every Google ad a competitor runs**: Search, YouTube, Shopping, Maps and Play. Search by brand name, domain, advertiser ID or Transparency Center URL. Each ad comes with its format, advertiser, first and last shown dates, days running, and image, preview and YouTube links.

Optionally add **per-country delivery with impression ranges and a per-platform breakdown**, plus creative variations. Ads cost **$0.90 per 1,000**.

### Why this one

- **Every input type:**
  - Brand names (matched to the right advertisers, falling back to the brand's domain).
  - Domains, advertiser IDs (AR…), and advertiser, domain or creative URLs.
- **Every filter:** region (any country, or anywhere), platform, format, shown-between dates.
- **Fast and complete:**
  - 100-ad pages and cursor pagination: 1,500 ads in under 7 seconds in testing.
  - No hard cap; big brands have 40,000+ ads.
- **Deep details (optional):**
  - Every country an ad ran in, with first and last dates.
  - Impression ranges and a per-platform split. Google publishes impressions for EU/EEA delivery.
  - Total impressions, all variations, and the YouTube video link for video ads when the preview exposes it.
- **Monitoring mode:** remembers the ads it has seen and returns only new ones. Schedule it daily for a competitor new-ads feed.
- **Reliable:**
  - Retries with backoff and proxy-session rotation on every request.
  - Optional automatic switch to residential proxy.
  - Clear input validation, so bad input fails before any charge.
  - It stops exactly at your maximum cost per run.

### Use cases

- Competitor ad research: creatives, messaging and how long ads have been running (long-running ads are usually winners).
- Agency pitches and audits: export every ad a prospect runs.
- Brand protection: find advertisers bidding on or imitating your brand or domain.
- Market research by country or platform, e.g. all YouTube video ads for a domain in the US.
- Daily monitoring of new competitor ads (monitoring mode plus a schedule).

### Input example

```json
{
  "queries": ["Canva", "nike.com", "AR06374349942554624001"],
  "region": "AU",
  "platforms": ["SEARCH", "YOUTUBE"],
  "adFormat": "ALL",
  "startDate": "2026-09-01",
  "maxAdsPerSearch": 200,
  "includeDetails": true
}
```

### Output example (with details)

```json
{
  "creativeId": "CR12963317279176523777",
  "advertiserId": "AR01625195283841286145",
  "advertiserName": "Shopify Inc.",
  "domain": "shopify.com",
  "format": "TEXT",
  "firstShown": "2026-04-10T04:05:15+00:00",
  "lastShown": "2026-10-17T12:29:06+00:00",
  "shownForDays": 192,
  "previewType": "image",
  "imageUrl": "https://tpc.googlesyndication.com/archive/simgad/9679469614907535245",
  "previewUrl": null,
  "videoUrl": null,
  "width": 348, "height": 200,
  "adUrl": "https://adstransparency.google.com/advertiser/AR01625195283841286145/creative/CR12963317279176523777?region=DE",
  "searchRegion": "DE",
  "regionsShown": [
    {"regionCode": "PT", "regionName": "Portugal", "impressionsMin": 1000, "impressionsMax": 2000,
     "firstShown": "2026-04-10", "lastShown": "2026-10-16",
     "platforms": [{"platform": "SEARCH", "impressionsMin": 1000, "impressionsMax": 2000}]}
  ],
  "regionCount": 30,
  "impressionsMin": 200000, "impressionsMax": 225000,
  "platformsShown": ["SEARCH", "SHOPPING"],
  "variationCount": 3
}
```

Other fields:

- `googleCreativeId`, `googleCustomerId`, `adGroupId` and `versionId` (taken from the preview link).
- `advertiserUrl`, `searchInput`, `searchType` and `scrapedAt`.
- `raw` (optional).

With *What to return = Advertisers only*, you get advertiser records: ID, legal name, country, verified flag, ad-count range and matching domains.

### Pricing (pay per event)

| Event | Price |
|---|---|
| Ad result | $0.0009 ($0.90 per 1,000 ads) |
| Ad details (only with *Include regions, impressions & variations*) | $0.0006 per ad |
| Advertiser record (advertiser lookup mode) | $0.0005 |
| Actor start | $0.00005 per GB of memory (set by Apify) |

With details on, ads cost $1.50 per 1,000 in total. There are no per-run fees.

### FAQ

**Why are text ads returned as images?** Google's Transparency Center renders text ads as images (`imageUrl`). It does not publish the ad text as text.

**Why are impressions empty for some ads?** Google only publishes impression ranges for ads delivered in the EU/EEA, under the Digital Services Act. Other regions show dates only.

**Brand name or domain?** A domain is exact: it returns every ad pointing to that site, from all advertisers including agencies. A brand name is matched to advertiser names. If there is no exact name match, the brand's own domain is used. The log shows which advertiser or domain each query resolved to.

**Is the platform filter exact?** Google does not document its platform codes. Our mapping (Search, YouTube, Maps, Play, Shopping) was inferred from observed data and matches the platforms shown on ad pages. Treat it as best effort.

**Do I need a proxy?** The default Apify datacenter proxy is enough. In testing, 300+ requests in 16 s from one IP produced only a few rate-limit responses, and all succeeded on retry. Residential proxy is optional for very large runs.

**How does monitoring work?** Turn on *Only new ads* and choose a store name. Each run saves the creative IDs it has seen and returns only new ones, so the first run is your baseline. Results are newest first, so a run stops paging when it reaches ads it has already reported.

### Daily health check

The prefill input (`canva.com`, 100 ads) returns results in a few seconds. A 10-ad version is in `test_inputs/00_selftest.json`.

### Legal notes

- The data comes from Google's public **Ads Transparency Center**, which Google publishes so the public can see who advertises.
- `adstransparency.google.com` publishes no robots.txt. However, Google's Terms of Service restrict automated access.
- The Actor collects ad and advertiser information only: business names, domains and creatives. Some advertisers are sole traders whose legal name is a person's name; treat those records under your privacy obligations (e.g. GDPR/Australian Privacy Act).
- Ad creatives are copyrighted by their owners. Use them for research and analysis, not republication.
- Not affiliated with or endorsed by Google.

# Actor input Schema

## `queries` (type: `array`):

Brand names (e.g. 'Canva'), domains (e.g. 'nike.com'), advertiser IDs (AR...) or Transparency Center URLs. The type is detected automatically. Brand names are matched to the closest advertisers (see 'Advertisers per brand query').

## `domains` (type: `array`):

Advertiser website domains, e.g. 'shopify.com'. Returns every ad that points to this domain, from all advertisers.

## `advertiserIds` (type: `array`):

Google advertiser IDs (start with AR), taken from a Transparency Center URL such as adstransparency.google.com/advertiser/AR0637...

## `startUrls` (type: `array`):

Advertiser, domain or single-creative URLs copied from adstransparency.google.com. A 'region' parameter in the URL is respected.

## `resultType` (type: `string`):

'ads' returns ad creatives. 'advertisers' only looks up brand queries and returns matching advertiser records (ID, legal name, country, verified flag, ad count range).

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

2-letter country code where the ads were shown (US, AU, GB, DE, ...), or 'anywhere'.

## `platforms` (type: `array`):

Only ads shown on these Google surfaces. Leave empty for all.

## `adFormat` (type: `string`):

Only ads of this format. Note: Google renders most text ads as images in the Transparency Center.

## `startDate` (type: `string`):

Only ads shown at some point in this window (YYYY-MM-DD).

## `endDate` (type: `string`):

End of the window (YYYY-MM-DD).

## `maxAdsPerSearch` (type: `integer`):

Maximum ads per query / domain / advertiser. 0 = no limit (big brands have tens of thousands of ads).

## `maxResults` (type: `integer`):

Hard cap across the whole run. 0 = no cap. Your 'Maximum cost per run' is always respected too.

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

How many matching advertisers to include for each brand-name query (best match first). Domains and IDs are exact and ignore this.

## `includeDetails` (type: `boolean`):

One extra lookup per ad: every country the ad ran in with first/last dates, impression ranges, per-platform impressions, total impressions and all creative variations. Video ads also get their YouTube link. Charged as a separate 'ad details' event.

## `extractVideoUrls` (type: `boolean`):

With details on, read the video preview to get the YouTube video ID and URL.

## `onlyNewAds` (type: `boolean`):

Remember ads seen in earlier runs and return only ones not seen before. Schedule the Actor daily to get a feed of new competitor ads.

## `monitorStoreName` (type: `string`):

Named key-value store that keeps the seen ads. Use a different name per monitoring project.

## `includeRawData` (type: `boolean`):

Attach the raw Transparency Center record to each item (for debugging).

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

Google limits requests per IP. Apify datacenter proxy is enough for most runs; residential is the safest for very large runs.

## `residentialFallback` (type: `boolean`):

After repeated blocks, finish the run on Apify residential proxy (uses your residential proxy traffic).

## `maxConcurrency` (type: `integer`):

How many searches/lookups run in parallel. Keep low (2-4) unless you use residential proxy.

## `maxRetries` (type: `integer`):

Retries per request; each retry rotates the proxy session.

## `requestDelayMs` (type: `integer`):

Politeness delay after each request.

## `pageSize` (type: `integer`):

Ads requested per page (10-100).

## Actor input object example

```json
{
  "queries": [
    "canva.com"
  ],
  "resultType": "ads",
  "region": "anywhere",
  "adFormat": "ALL",
  "maxAdsPerSearch": 100,
  "maxResults": 0,
  "maxAdvertisersPerQuery": 3,
  "includeDetails": false,
  "extractVideoUrls": true,
  "onlyNewAds": false,
  "monitorStoreName": "ads-transparency-monitor",
  "includeRawData": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true,
  "maxConcurrency": 3,
  "maxRetries": 5,
  "requestDelayMs": 250,
  "pageSize": 40
}
```

# Actor output Schema

## `results` (type: `string`):

One row per ad creative: advertiser, format, first/last shown, days running, preview/image/YouTube links.

## `adDetails` (type: `string`):

Per-ad regions, impression ranges and platform breakdown (filled when 'Include regions' is on).

## `advertisers` (type: `string`):

Advertiser records matched by the search queries.

## `runStats` (type: `string`):

RUN_STATS record in the default key-value store: requests, successes, retries, blocks, failures and notes.

# 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 = {
    "queries": [
        "canva.com"
    ],
    "region": "anywhere",
    "maxAdsPerSearch": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("clearscrape/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 = {
    "queries": ["canva.com"],
    "region": "anywhere",
    "maxAdsPerSearch": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("clearscrape/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 '{
  "queries": [
    "canva.com"
  ],
  "region": "anywhere",
  "maxAdsPerSearch": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call clearscrape/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,clearscrape/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/BONMXTt7mTNJbeIo1/builds/7eO7wq0KL7spbnfaV/openapi.json
