# 🔥 Google Ads Transparency Center Scraper (`extractmaster01/google-ads-scraper`) Actor

Extract ad creatives from Google Ads Transparency Center Scraper. Scrape VIDEO, IMAGE and TEXT ads for any advertiser — search by domain, name, or ID. Filter by region, platform and date. Pay per event — $1 per 1,000 ads.

- **URL**: https://apify.com/extractmaster01/google-ads-scraper.md
- **Developed by:** [extractmaster01](https://apify.com/extractmaster01) (community)
- **Categories:** Automation, E-commerce, SEO tools
- **Features:** Limited permissions
- **Stats:** 8 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 ad scrapeds

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

Extract ad creatives from the [Google Ads Transparency Center](https://adstransparency.google.com/). Search by domain, advertiser name, or Google Advertiser ID and get structured data for VIDEO, IMAGE, and TEXT ads — with filters for region, platform, and date range.

No login required. No browser. Pure HTTP.

***

### Why Use This Scraper?

- **Three search modes** — domain (`nike.com`), keyword (`"Nike"`), or advertiser ID (`AR…`). Auto-detected.
- **Multiple targets in one run** — scrape a list of competitors simultaneously using `searchTargets`.
- **All ad formats** — VIDEO with YouTube URL, IMAGE with CDN image URL, TEXT with ad copy when available.
- **All Google platforms** — Search, YouTube, Shopping, Maps, Play, or all at once.
- **170+ regions** — filter by any country or search globally.
- **Date range filters** — last 7, 30, 90 days, all time, or custom `startDate`/`endDate`.
- **Active date range** — `firstShown` and `lastShown` for every ad.
- **Fast and cheap** — 512 MB memory, no browser overhead.

***

### Use Cases

**Competitive Intelligence**
Track every ad a competitor runs across Google platforms. Use `numServedDays` to identify long-running creatives — ads that run 60+ days are almost always profitable.

**Ad Creative Research**
Build a library of IMAGE and VIDEO ad creatives from any brand. Every VIDEO ad includes a direct YouTube watch URL and thumbnail.

**Brand Protection**
Find who is advertising on your brand name or domain. `advertiserLegalName` and `isVerified` help distinguish authorized partners from unauthorized advertisers.

**Lead Generation**
Identify companies actively spending on Google Ads in your target vertical — a strong buying-intent signal for outbound sales.

**Market Research**
Combine `region` and `platform` filters to map the competitive landscape in any country or channel.

***

### Getting Started

#### Search by domain

```json
{
  "searchQuery": "nike.com",
  "maxResults": 100
}
```

#### Search by keyword

```json
{
  "searchQuery": "cloud hosting",
  "maxResults": 50
}
```

#### Search by advertiser ID

```json
{
  "searchQuery": "AR16735076323512287233",
  "maxResults": 200
}
```

#### Multiple competitors, filtered

```json
{
  "searchTargets": ["competitor-a.com", "competitor-b.com"],
  "region": "US",
  "platform": "YOUTUBE",
  "datePreset": "LAST_30_DAYS",
  "maxResults": 300
}
```

***

### Output

Each result is one ad creative. Example for a VIDEO ad:

```json
{
  "creativeId": "CR01422152672017907713",
  "advertiserId": "AR17828074650563772417",
  "advertiserName": "Tesla Inc.",
  "advertiserUrl": "https://adstransparency.google.com/advertiser/AR17828074650563772417",
  "advertiserLegalName": "Tesla, Inc.",
  "advertiserCountry": "US",
  "isVerified": true,
  "format": "VIDEO",
  "adFormat": "video",
  "youtubeVideoUrl": "https://www.youtube.com/watch?v=misASga7klE",
  "imageUrl": "https://i.ytimg.com/vi/misASga7klE/hqdefault.jpg",
  "previewUrl": "https://www.youtube.com/watch?v=misASga7klE",
  "adUrl": "https://adstransparency.google.com/advertiser/AR17828074650563772417/creative/CR01422152672017907713?region=anywhere",
  "firstShown": "2026-03-01",
  "lastShown": "2026-06-07",
  "numServedDays": 99,
  "approxDaysShown": 99,
  "scrapedAt": "2026-06-08T14:23:01.000Z"
}
```

#### Field Reference

| Field | Type | Description |
|---|---|---|
| `creativeId` | string | Unique ad creative ID |
| `advertiserId` | string | Google advertiser ID (`AR…`) |
| `advertiserName` | string | Advertiser display name |
| `advertiserUrl` | string | Link to the advertiser's Transparency Center page |
| `advertiserLegalName` | string? | Legal entity name registered with Google |
| `advertiserCountry` | string? | Country of legal registration |
| `isVerified` | boolean? | Whether the advertiser passed Google's identity verification |
| `format` | string | `VIDEO`, `IMAGE`, or `TEXT` |
| `adFormat` | string | Lowercase alias: `video`, `image`, or `text` |
| `youtubeVideoUrl` | string? | YouTube watch URL — VIDEO ads only |
| `imageUrl` | string? | Direct URL to the image asset (IMAGE ads) or video thumbnail (VIDEO ads) |
| `adCopy` | array? | Ad headline text — TEXT ads only, when available |
| `shoppingProductTitle` | string? | Product title — Shopping IMAGE ads only |
| `previewUrl` | string? | YouTube URL for VIDEO ads; Transparency Center page for IMAGE/TEXT |
| `adUrl` | string | Transparency Center page URL for this creative |
| `firstShown` | string? | Date the ad was first shown (`YYYY-MM-DD`) |
| `lastShown` | string? | Date the ad was last shown (`YYYY-MM-DD`) |
| `numServedDays` | number? | Number of days the ad has been running |
| `approxDaysShown` | number? | Alias for `numServedDays` |
| `scrapedAt` | string | Timestamp of when this record was scraped |

> Enable `includeStats: true` to also get `regionStats` (per-country date breakdown), `targeting` (audience category flags), and `impressionsTotal` (EU DSA political ads only).

***

### Input Parameters

#### Search

| Parameter | Type | Description |
|---|---|---|
| `searchQuery` | string | Domain, keyword, or `AR…` ID. Auto-detects type. |
| `searchTargets` | string\[] | List of domains, keywords, or IDs for multi-advertiser runs. |

#### Limits

| Parameter | Type | Default | Description |
|---|---|---|---|
| `maxResults` | integer | `100` | Max ads per advertiser. Set to `0` for unlimited. |
| `maxAdvertisersPerKeyword` | integer | `1` | How many advertisers to follow when a keyword matches multiple accounts. |

#### Filters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `region` | string | `anywhere` | ISO country code (`US`, `BR`, `DE`…) or `anywhere` for global. |
| `platform` | string | `ALL` | `SEARCH`, `YOUTUBE`, `SHOPPING`, `MAPS`, `PLAY`, or `ALL`. |
| `adFormat` | string | `ALL` | `VIDEO`, `IMAGE`, `TEXT`, or `ALL`. |
| `datePreset` | string | `ALL_TIME` | `LAST_7_DAYS`, `LAST_30_DAYS`, `LAST_90_DAYS`, or `ALL_TIME`. |
| `startDate` | string | — | Custom start date `YYYY-MM-DD`. Overrides `datePreset`. |
| `endDate` | string | — | Custom end date `YYYY-MM-DD`. Overrides `datePreset`. |

> Date filtering is applied client-side after fetching. You are only charged for ads that match your filters and are saved to the dataset.

#### Advanced

| Parameter | Type | Default | Description |
|---|---|---|---|
| `proxyConfiguration` | object | Apify proxy (residential) | Proxy settings. Defaults to residential IPs. If Google starts rate-limiting (HTTP 429) a run, the Actor automatically escalates to residential proxy — even overriding a different setting you provided — so the run can still complete instead of failing. |
| `includeStats` | boolean | `false` | Add `regionStats`, `targeting`, and `impressions` to each result. |
| `skipDetails` | boolean | `false` | Skip the per-ad detail fetch. Returns core fields only — much faster for large discovery runs where image URLs and video links are not needed. |

***

### Pricing

This Actor uses **Pay Per Event** billing:

| Event | Price |
|---|---|
| Run started | $0.005 per run |
| Ad scraped | $0.001 per ad |

**Total cost = $0.005 + (number of ads × $0.001)**

| Example | Cost |
|---|---|
| 100 ads | ~$0.11 |
| 1,000 ads | ~$1.01 |
| 10,000 ads | ~$10.01 |

You are only charged for ads that match your filters and are saved to the dataset. No subscription, no minimum.

***

### API Usage

#### Node.js

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

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('YOUR_ACTOR_ID').call({
  searchQuery: 'nike.com',
  maxResults: 100,
  adFormat: 'VIDEO',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_TOKEN')
run = client.actor('YOUR_ACTOR_ID').call(run_input={
    'searchQuery': 'nike.com',
    'maxResults': 100,
    'adFormat': 'VIDEO',
})
items = list(client.dataset(run['defaultDatasetId']).iterate_items())
```

***

### Integrations

Export as JSON, CSV, Excel, XML, or RSS. Connect to 1,500+ apps:

- **Google Sheets** — export directly to a spreadsheet for team analysis.
- **Slack / Email** — get notified when a competitor launches new ads.
- **Clay / Airtable** — enrich prospect lists with ad activity signals.
- **n8n / Make / Zapier** — trigger workflows when new creatives appear.
- **Apify API** — schedule automated runs and pull data programmatically.

***

### FAQ

**Do I need a Google account?**
No. The Google Ads Transparency Center is publicly accessible without login.

**How many ads can I get per run?**
As many as you need. The default is 100 per advertiser. Set `maxResults: 0` for unlimited. Use `searchTargets` to scrape multiple advertisers in one run.

**Can I search by domain?**
Yes. Enter a domain like `"nike.com"` and the scraper automatically finds the associated advertiser and fetches their ads.

**Why is `imageUrl` missing for some IMAGE ads?**
Shopping IMAGE ads load their product photos dynamically at runtime — the image URL is not available in the public API. Display IMAGE ads will have `imageUrl` populated.

**Why is `adCopy` empty for most TEXT ads?**
Most modern TEXT ads are responsive display ads served via JavaScript. The ad copy is not exposed in the public API. `adCopy` is populated for older ads that include inline HTML copy.

**What's the difference between `previewUrl` and `adUrl`?**
`adUrl` always points to the Transparency Center page for the creative. For VIDEO ads, `previewUrl` is the YouTube watch URL. For IMAGE and TEXT ads both fields point to the Transparency Center page.

**How does date filtering work?**
Google's API does not support server-side date filtering. The scraper filters client-side — you are only charged for ads that match your date range and are saved to the dataset.

**Why did my run use residential proxy even though I set a different `proxyConfiguration`?**
Google's Ads Transparency backend rate-limits (HTTP 429) some proxy types very aggressively. If the Actor detects a sustained run of failures that looks like a 429 wall, it automatically escalates to residential proxy for the rest of the run — even if you set `useApifyProxy: false` or a non-residential group — so your run can finish instead of dying partway through. This only kicks in after repeated real failures, and happens at most once per run.

**Will I ever be charged twice for the same ad?**
No. Long runs on the Apify platform can occasionally be migrated to a different server for routine infrastructure maintenance — this is normal and outside the Actor's control. The Actor checkpoints its progress (which ads were already charged, and where it was in the results) so that if this happens, it resumes exactly where it left off instead of re-processing and re-charging ads you already received.

**The actor returned 0 ads — what do I do?**

1. Verify the advertiser has active ads at [adstransparency.google.com](https://adstransparency.google.com).
2. Try `"region": "anywhere"` — the advertiser may only run ads in specific countries.
3. Remove format and platform filters — the combination may produce zero results.
4. For keyword searches, try the domain (`brand.com`) or a direct `AR…` ID instead.

**How do I find an advertiser ID?**
Search at [adstransparency.google.com](https://adstransparency.google.com). The ID appears in the URL — e.g. `.../advertiser/AR17828074650563772417`. You can also paste the full URL directly into `searchQuery`.

**How is this different from the Google Ads API?**
The Google Ads API requires an approved developer account and only shows your own campaigns. This scraper accesses publicly available data from the Transparency Center — any advertiser, no credentials required.

***

### Legal

The Google Ads Transparency Center is a public accountability tool built by Google for regulatory compliance. All data it contains is intentionally made public. Users are responsible for complying with applicable laws and Google's Terms of Service. Do not use collected data for spam, harassment, or any unlawful purpose.

# Actor input Schema

## `searchQuery` (type: `string`):

Keyword, domain (e.g. nike.com), or Google Advertiser ID (e.g. AR16735076323512287233). Auto-detects input type.

## `searchTargets` (type: `array`):

List of advertiser URLs, advertiser IDs (starting with 'AR'), domains, or search keywords. Use this to scrape multiple advertisers in one run.

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

Maximum number of ads to return per advertiser. Set to 0 for unlimited.

## `maxAdvertisersPerKeyword` (type: `integer`):

When searching by keyword or advertiser name, how many matching advertiser accounts to follow. Default is 1 (first result). Increase to discover multiple advertisers with similar names.

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

ISO 3166-1 alpha-2 country code where ads were shown (e.g. US, BR, DE). Use 'anywhere' for global search.

## `platform` (type: `string`):

Filter ads by the platform where they appeared.

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

Filter by the creative format of the ad.

## `datePreset` (type: `string`):

Filter ads by when they were shown. Use a preset window or set custom startDate/endDate instead.

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

Show only ads that appeared on or after this date (YYYY-MM-DD). Overrides datePreset if set.

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

Show only ads that appeared on or before this date (YYYY-MM-DD). Overrides datePreset if set.

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

Select proxies to be used by the crawler. Residential IPs improve reliability on large-scale runs. Defaults to RESIDENTIAL — Google's Ads Transparency Center backend rate-limits (HTTP 429) datacenter IPs after ~30 requests.

## `includeStats` (type: `boolean`):

Include regionStats, targeting, and impressions in the output. Disabled by default for a clean, compact result. Enable for deeper analysis of where and how ads were served.

## `skipDetails` (type: `boolean`):

Skip the per-ad detail API call. Returns basic fields only (creativeId, format, firstShown, lastShown, numServedDays, previewUrl). Much faster and cheaper for large-scale discovery runs where imageUrl and adCopy are not needed.

## Actor input object example

```json
{
  "searchQuery": "AR17828074650563772417",
  "maxResults": 5,
  "maxAdvertisersPerKeyword": 1,
  "region": "anywhere",
  "platform": "ALL",
  "adFormat": "ALL",
  "datePreset": "ALL_TIME",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "includeStats": false,
  "skipDetails": false
}
```

# 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 = {
    "searchQuery": "AR17828074650563772417",
    "maxResults": 5,
    "region": "anywhere",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("extractmaster01/google-ads-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 = {
    "searchQuery": "AR17828074650563772417",
    "maxResults": 5,
    "region": "anywhere",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("extractmaster01/google-ads-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 '{
  "searchQuery": "AR17828074650563772417",
  "maxResults": 5,
  "region": "anywhere",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call extractmaster01/google-ads-scraper --silent --output-dataset

```

## MCP server setup

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