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

📊 Scrape any advertiser's Google ads from the official Ads Transparency Center: every creative with its image or preview, format, first and last run dates, impression range, ad category and the per-country breakdown. Search by brand name or domain — no ids. Pay per result.

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

## Pricing

from $1.36 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 API - Competitor Ads

See every ad a competitor runs through Google — Search, Display, YouTube, Shopping and Maps — straight from Google's own [Ads Transparency Center](https://adstransparency.google.com), and export it as JSON, CSV or Excel, or pull it from the API.

⚡ **Give a brand name or a domain — no ids to look up.** For every ad you get the creative itself (the image URL, or Google's render for a video), the format, the advertiser's verified name, the first and last day it ran, and its page on the Transparency Center. Turn on full details and each ad also carries **the impression range Google reports, the ad category, and a per-country breakdown** — impressions and run dates for each of the countries the ad appeared in. Filter by country, by format and by the dates an ad started or stopped running, so you can isolate exactly what a competitor launched last month or quietly killed. **No login, no cookies, no browser.** Pay per result.

[![Apify Actor](https://apify.com/actor-badge?actor=scrapifier/google-ads-transparency-scraper)](https://apify.com/scrapifier/google-ads-transparency-scraper)

### 🎯 Why scrape the Ads Transparency Center?

- **Competitive ad research**: pull a competitor's entire live ad set, see which creatives they keep running for months and which they dropped after a week.
- **Creative inspiration and swipe files**: download the image of every display ad, and keep Google's render of every video ad, with the date range each one ran.
- **Spend and reach proxies**: Google publishes an impression range per ad and per country. It is not a spend figure, but it is the closest public signal of which creatives a brand actually puts weight behind.
- **Market entry and localisation**: the per-country breakdown shows which markets a brand advertises in, when it started there, and whether it is still active.
- **Agency pitches and audits**: walk into a pitch with the prospect's own ad history, their categories, and how their rivals compare.
- **Monitoring**: put the Actor on a schedule with **First shown after** set to the start of the period you care about, and get only the ads launched since.
- **Ad-tech and research datasets**: build a dated corpus of creatives, categories and impression bands across a whole sector.

### 📊 What data does it extract?

#### Ads — one row per creative

| Field | Description |
|---|---|
| `creativeId`, `url` | Google's id for the ad and its page on the Transparency Center |
| `advertiserId`, `advertiserName`, `advertiserUrl` | The verified advertiser behind the ad |
| `format` | `image`, `video` or `text` |
| `imageUrl`, `widthPx`, `heightPx` | Direct link to the image of an image ad, and its size |
| `previewUrl` | Google's own render, for video and rich ads |
| `firstShown`, `firstShownDate`, `lastShown`, `lastShownDate` | When the ad started and last ran |
| `country`, `matchedInput` | The country the run was scoped to, and the input the row came from |

With **Full details** on, every row additionally carries:

- `impressionsMin`, `impressionsMax` — the impression range Google reports for the ad.
- `adCategory`, `adCategoryId` — the category Google files it under, e.g. *Apparel & Accessories*.
- `countriesShownIn[]` — one entry per country, each with its own impression range and its own first and last run dates.
- `countryCount`, `platformCount` — how many countries and how many Google surfaces the ad ran on.

#### Advertisers — one row per advertiser

`advertiserId`, `advertiserName`, `advertiserCountry` (the country Google verified them in), `adsMin` and `adsMax` (how many ads they are running), `isVerified`, `url`. Useful to pick the right legal entity before a big run: searching *Booking.com* matches ten advertisers, and this mode shows you which one runs 16 million ads and which one runs eleven.

### 🚀 How to use it

1. Put one or more **advertisers** in: a brand name (`Booking.com`), a domain (`nike.com`), a Transparency Center link, or an advertiser id. Brand names are matched against Google's verified advertisers; domains are searched directly in the ads.
2. Choose the **data type**: `creatives` (every ad) or `advertisers` (the identity card and ad volume of whoever matches).
3. Pick a **country**, or leave *Worldwide*.
4. Turn on **Full details** if you want impressions, categories and the per-country breakdown.
5. Narrow with **ad formats** and the **first shown / last shown** dates.
6. Set **Max rows** (`100` prefilled, `0` = no limit) — you pay per row, and a large advertiser runs tens of thousands of ads.
7. Click **Start**, then export from the **Storage** tab as JSON, CSV, Excel or XML, or read the dataset from the API.

### 📥 Input parameters

| Field | Key | Type | Default | Description |
|---|---|---|---|---|
| Advertisers | `advertisers` | array | `["nike.com"]` | Brand names, domains, Transparency Center URLs or advertiser ids. |
| Data type | `dataType` | select | `creatives` | `creatives` or `advertisers`. |
| Country | `country` | select | `Worldwide` | Every country by name. Scopes which ads count. |
| Full details | `includeDetails` | boolean | `false` | Adds impressions, ad category and the per-country breakdown. One extra request per ad. |
| Ad formats | `formats` | select (multiple) | all | `image`, `video`, `text`. |
| First shown after | `firstShownAfter` | date | none | Only ads that started on or after this date. |
| Last shown before | `lastShownBefore` | date | none | Only ads last seen on or before this date. |
| Max ads per advertiser | `maxAdsPerAdvertiser` | integer | `0` | Per-advertiser cap. `0` = no cap. |
| Max rows for the run | `maxItems` | integer | `100` | Hard stop across every input. `0` = no limit. |
| Flatten nested fields | `flatten` | boolean | `false` | One text column per field, for clean CSV / Excel. |
| Report what each input returned | `emitInputStatus` | boolean | `true` | Adds `input_status` to the run's OUTPUT record. |
| Proxy | `proxyConfiguration` | object | Apify Proxy | On by default; the Transparency Center paces how many requests one IP may send, so rotation keeps long runs steady. |

### 📤 Output example

```json
{
  "type": "creative",
  "creativeId": "CR05547927024246456321",
  "advertiserId": "AR18378488041124659201",
  "advertiserName": "Nike Retail BV",
  "format": "image",
  "imageUrl": "https://tpc.googlesyndication.com/archive/simgad/1195506655557789793",
  "widthPx": 381,
  "heightPx": 105,
  "firstShownDate": "2025-10-22",
  "lastShownDate": "2026-10-17",
  "impressionsMin": 125000,
  "impressionsMax": 150000,
  "adCategory": "Apparel & Accessories",
  "countryCount": 11,
  "countriesShownIn": [
    { "country": "Spain", "impressionsMin": 125000, "impressionsMax": 150000,
      "firstShownDate": "2025-10-22", "lastShownDate": "2026-10-17" },
    { "country": "Portugal", "impressionsMin": null, "impressionsMax": 1000,
      "firstShownDate": "2025-10-22", "lastShownDate": "2026-10-09" }
  ],
  "url": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR05547927024246456321",
  "country": "France",
  "matchedInput": "nike.com"
}
```

### 💡 Ready-to-run examples

**1. Every ad a competitor is running right now**

```json
{ "advertisers": ["booking.com"], "includeDetails": true, "maxItems": 500 }
```

**2. What did they launch recently?**

```json
{
  "advertisers": ["Nike"],
  "firstShownAfter": "2026-01-01",
  "maxItems": 2000
}
```

Dates and formats are pushed to the Transparency Center's own filters, so this
reads only the ads that can match instead of the advertiser's whole history.

**3. What did they stop running?**

```json
{ "advertisers": ["Salesforce"], "lastShownBefore": "2026-09-01" }
```

**4. Video ads only, in one market**

```json
{
  "advertisers": ["nike.com"],
  "formats": ["video"],
  "country": "Germany",
  "includeDetails": true
}
```

**5. Which legal entity should I track?**

```json
{ "advertisers": ["Booking.com"], "dataType": "advertisers" }
```

**6. A whole competitive set in one run**

```json
{
  "advertisers": ["nike.com", "adidas.com", "newbalance.com"],
  "maxAdsPerAdvertiser": 200,
  "includeDetails": true
}
```

### 💰 Pricing

Pay per result, no subscription and no platform usage added on top: **$2.00 per 1,000 rows**, with lower rates on higher Apify plans. A row is one ad or one advertiser. So a competitor's 500 live ads cost **$1.00**, and a 10,000-ad sweep costs **$20**. Set **Max rows** on your first runs to keep every run predictable.

### ⚙️ Performance and limits

- **No browser, no login, no cookies** — the Actor reads the Transparency Center's own public data feed, 40 ads per request.
- **Rate limiting** is handled with automatic back-off and IP rotation through Apify Proxy; a single IP can only ask for so much.
- **Honest reporting.** The `input_status` report in OUTPUT lists, per input: how many rows it returned, which advertiser a brand name resolved to, which other advertisers matched that same name, how many pages were read, and why anything came back empty.
- **Long runs stay safe.** The Actor watches the run timeout and finishes cleanly with the data already collected, and it respects your max-cost-per-run setting.
- **Filters by date and format** are sent to the Transparency Center itself, so a narrow request reads only the ads that can match: asking for one brand's video ads takes a couple of requests rather than a sweep of its entire back catalogue. The exact date boundaries are applied on the results, because the site filters on the days an ad was *running* rather than the day it started.

### ❓ FAQ

**Do I need a Google account?** No. The Transparency Center is public and the Actor never signs in.

**Is the impression number a spend figure?** No. Google publishes a *range* of impressions per ad and per country, not spend and not clicks. It tells you which creatives carry weight relative to each other — treat it as a signal, not an invoice.

**Why does a brand name match several advertisers?** Large brands run ads through several verified legal entities (country subsidiaries, agencies). Google's own suggestions are not ordered by relevance, so the Actor picks the entity that actually carries the name **and runs the most ads** — searching *Nike* gives you Nike, Inc. and its thousands of ads, not the unrelated one-ad advertiser Google happens to list first. The runners-up are listed with their ad volume in `input_status`, and you can always pass an advertiser id to pin one exactly. A domain that matches no advertiser at all is searched in the ads themselves.

**Why do some ads have no category or no country breakdown?** Google only publishes those for part of its inventory. The fields are simply absent on those rows rather than guessed.

**Can I get the ad's landing page URL?** Not from this data — Google does not publish the destination URL in the Transparency Center. You get the creative, its dates, its impressions and its countries.

**Is there an official bulk alternative?** Yes, and it is worth knowing: Google publishes a [BigQuery public dataset](https://console.cloud.google.com/marketplace/details/bigquery-public-data/google-ads-transparency-center) covering the EEA and Turkey. It needs a Google Cloud account and SQL, and it is not live per advertiser. This Actor is for pulling one advertiser, today, into a spreadsheet or a pipeline without any of that setup.

**Is this legal?** The Actor reads only the public transparency data Google publishes for everyone, which exists precisely so ads can be inspected. You are responsible for using the output in compliance with applicable laws and Google's terms.

### 🔗 Related scrapers

[Trustpilot](https://apify.com/scrapifier/trustpilot-reviews-scraper) · [Capterra](https://apify.com/scrapifier/capterra-reviews-scraper) · [Bilibili](https://apify.com/scrapifier/bilibili-scraper) · [Airbnb](https://apify.com/scrapifier/airbnb-scraper) · [Glassdoor](https://apify.com/scrapifier/glassdoor-reviews-scraper) · [Indeed](https://apify.com/scrapifier/indeed-jobs-scraper) · [Upwork](https://apify.com/scrapifier/upwork-jobs-scraper)

### 💬 Support

Found a bug, a missing field, or an advertiser that returns nothing? Open an issue on the Actor's **Issues** tab with your input and the run id.

# Actor input Schema

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

Who to track. A brand name is matched against Google's verified advertisers ("Booking.com", "Nike"); a domain is searched directly in the ads ("nike.com", "salesforce.com"); a Transparency Center link or an advertiser id also works. OUTPUT reports which advertiser each name resolved to, and lists the other advertisers that matched the same name.

## `dataType` (type: `string`):

Ads: every creative the advertiser is running. Advertisers: just the identity card of whoever matches your search, with their ad volume — useful to pick the right legal entity before a big run.

## `country` (type: `string`):

Only count ads shown in this country. Worldwide keeps every country, and each ad still carries its own per-country breakdown when full details are on.

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

Adds the impression range, the ad category and the per-country breakdown (impressions and dates for each country the ad ran in) to every row. One extra request per ad.

## `formats` (type: `array`):

Empty = every format.

## `firstShownAfter` (type: `string`):

YYYY-MM-DD. Only ads that started running on or after this date — the way to see what a competitor launched recently.

## `lastShownBefore` (type: `string`):

YYYY-MM-DD. Only ads last seen on or before this date — the way to see what a competitor has stopped running.

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

Cap for each advertiser or search term separately. 0 = no per-advertiser cap. Big advertisers run tens of thousands of ads.

## `maxItems` (type: `integer`):

Hard stop for the run, across every input. 0 = no limit.

## `flatten` (type: `boolean`):

Turns the per-country breakdown into a single text column so a CSV or Excel export stays readable.

## `emitInputStatus` (type: `boolean`):

Adds an input_status report to the run's OUTPUT record: rows collected per advertiser, which advertiser a name resolved to, other advertisers that matched the same name, and why anything came back empty.

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

Apify Proxy is on by default and rotates IPs, which keeps long runs steady — the Transparency Center paces how many requests one IP may send.

## `debug` (type: `boolean`):

Adds extra detail to the run log when you are debugging an input.

## Actor input object example

```json
{
  "advertisers": [
    "nike.com"
  ],
  "dataType": "creatives",
  "country": "Worldwide",
  "includeDetails": false,
  "maxItems": 100,
  "flatten": false,
  "emitInputStatus": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "debug": false
}
```

# Actor output Schema

## `rows` (type: `string`):

All ad / advertiser rows extracted by this run.

# 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.com"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapifier/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.com"],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapifier/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.com"
  ],
  "maxItems": 100
}' |
apify call scrapifier/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

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