# Google Ads Transparency Scraper — Competitor Ads, Copy & Video (`cleancut/google-ads-transparency-scraper`) Actor

Get every Google ad a competitor runs from the Ads Transparency Center, by domain, advertiser or URL: ad copy, images, YouTube videos, Shopping products, dates, countries, reach and EU targeting, all included. New-ad monitor. Pay per ad; errors and advertiser lookups are free.

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

## Pricing

from $0.10 / 1,000 ad with all details

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 Scraper — Competitor Ads, Copy & Video

Get **every Google ad a competitor runs** from the **Google Ads Transparency Center**: search by **domain, advertiser name, advertiser ID or Transparency Center URL** and get each ad's **headline and description, image, YouTube video, Shopping product, first and last shown dates, countries, reach and EU audience selection**, in one clean table. Schedule it with a monitor name to get **only the new ads** every week.

**You only pay for ads delivered: $0.10 per 1,000 ads with every detail included.** Ad copy, media, countries and advertiser data never cost extra; errors and advertiser lookups are free.

### What can it do?

- 🔎 **Any way you know the advertiser** — a domain (`nike.com`: every ad that points to it, from the brand and its agencies), a name (`Shopify`), an advertiser ID (`AR16735076323512287233`) or a Transparency Center URL (advertiser page, ad page or domain search). Mix them in one run.
- ✍️ **The ad copy, free** — headline, description, display URL, business name and sitelinks of text ads; headline, long headline, description and call to action of video ads; product title and merchant of Shopping ads.
- 🖼️ **Images & videos** — image URL with width and height, **YouTube video ID and link** with thumbnail, HTML5 creatives (DV360 / Campaign Manager), Google's preview link, every variation of the ad and its Google Ads IDs (customer, creative, ad group).
- 📅 **How long it has been running** — first and last shown date, days running and a **still running** flag, newest ads first.
- 🌍 **Where it ran** — every country with its own dates and, for the EU, **how many times it was shown, in total and per platform** (Search, YouTube, Shopping, Maps, Play), as Google publishes it.
- 🇪🇺 **EU transparency (DSA), free** — who paid for the ad, Google's topic (Apparel, Finance…), total reach and how the audience was selected (demographics, locations, contextual signals, customer lists, topics of interest).
- 🏢 **Advertiser data** — legal name, country, **identity verified or not** and the advertiser's Transparency Center page.
- 🎛️ **The Transparency Center filters** — country, platform (Search, YouTube, Shopping, Maps, Play), format (text, image, video) and date range (exact dates or "last 30 days").
- 🔔 **New-ad monitor** — schedule it daily or weekly: each ad is marked new or already seen, or turn on **Only new ads** and pay only for the new ones.
- 🆓 **Free advertiser lookup** — see who advertises behind each search, whether they are verified and how many ads they have, before paying for anything.
- ⚡ **Fast & lightweight** — plain HTTP, no browser: hundreds of ads per minute.

### Who is it for?

- 📊 **Marketing agencies & PPC consultants** — audit a prospect's or a client's competitors in minutes: what they say, which formats they use, where and since when.
- 🛍️ **E-commerce brands** — track competitors' Shopping and YouTube ads, offers and seasonal campaigns every week.
- 🎨 **Creative teams** — collect the copy and the creatives of a whole category to find angles that work.
- 🔍 **Competitive-intelligence & research teams** — build datasets of advertisers, verification status, countries and reach.
- 🤖 **AI agents** — call it through the [Apify MCP server](https://mcp.apify.com); every field is documented for the model.

### Input example

```json
{
  "searches": ["nike.com", "Shopify", "AR16735076323512287233"],
  "region": "anywhere",
  "platforms": ["YOUTUBE"],
  "adFormat": "video",
  "shownAfter": "30 days",
  "maxAdsPerSearch": 200,
  "detailLevel": "full",
  "monitorName": "competitors-weekly"
}
```

The input also accepts the names other Ads Transparency Actors use (`queries`, `domains`, `advertiserIds`, `startUrls`, `startDate`, `endDate`, `resultType`, `includeDetails`, `onlyNewAds`), so existing integrations work as they are.

### Output example

A real ad (searched on 4 Nov 2026), shortened:

```json
{
  "status": "ok",
  "search": "nike.com",
  "advertiserId": "AR18378488041124659201",
  "advertiserName": "Nike Retail BV",
  "advertiserLegalName": "Nike Retail BV",
  "advertiserCountry": "NL",
  "advertiserVerified": true,
  "paidBy": "Nike Retail BV",
  "domain": "nike.com",
  "creativeId": "CR17431850113482883073",
  "format": "video",
  "topic": "Apparel",
  "firstShown": "2026-06-20",
  "lastShown": "2026-11-04",
  "daysShown": 138,
  "isActive": true,
  "thumbnailUrl": "https://i.ytimg.com/vi/…/hqdefault.jpg",
  "videoUrl": "https://www.youtube.com/watch?v=…",
  "regions": [
    { "regionCode": "IT", "regionName": "Italy", "firstShown": "2026-06-20", "lastShown": "2026-11-04", "impressionsMin": 5000, "impressionsMax": 6000 }
  ],
  "impressionsMin": 5000,
  "impressionsMax": 6000,
  "audienceSelection": { "demographics": "included", "locations": "included_and_excluded", "contextualSignals": "included_and_excluded", "customerLists": "included", "topicsOfInterest": "included" },
  "adUrl": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR17431850113482883073?region=anywhere",
  "scrapedAt": "2026-11-04T21:40:12.512Z"
}
```

A text ad comes with its copy, e.g. `"headline": "Nike® Official Site - Free Shipping On Orders $75+"`, `"description": "Designed and created to enable outstanding performance, Nike® football tops."`, `"displayUrl": "www.nike.com/"` and `"sitelinks": ["Nike Football Gear", "Shop Nike® Football Tops", "Shop Nike® NFL Rivalries"]`.

#### Output views

The Output tab (and the API, with `?view=`) offers ready-made tables:

| View | What you get |
|---|---|
| **Ads** | One row per ad: preview, advertiser, format, headline, description, dates, days running, still running and the Transparency Center link |
| **Ad copy** | Headline, description, display URL, business name, sitelinks, Shopping product and merchant |
| **Images & videos** | Image, YouTube video, HTML5 creative, Google preview and number of variations |
| **Countries & reach** | One row per ad and country with dates and times shown, also per platform (EU) |
| **EU transparency (DSA)** | Who paid, Google's topic, platforms, total reach and audience selection |
| **Advertisers** | Advertiser lookup: verified or not, legal name, country, approximate ads |
| **New ads (monitor)** | New vs already seen in previous runs |
| **Errors (free)** | Searches that could not be completed, and why |

Every field is documented in the dataset schema (type, description and example), so AI agents and integrations know exactly what they get. The key-value store has a `SUMMARY` of the run.

### Errors (free)

Searches that can't be completed produce a free row with `status: "error"` at the end of the dataset:

| errorCode | Meaning |
|---|---|
| `INVALID_SEARCH` | The line is not a domain, advertiser name, advertiser ID or Transparency Center URL |
| `ADVERTISER_NOT_FOUND` | No advertiser with that name (the message lists matching domains you can search instead) |
| `NO_ADS` | The advertiser or domain has no ads with the selected country, platform, format and dates |
| `BLOCKED` | Google showed a CAPTCHA to the proxy IP — keep the default RESIDENTIAL proxy, lower **Parallel connections** or try again later |
| `RATE_LIMITED` / `SOURCE_ERROR` / `REQUEST_FAILED` | Google kept answering with an error after several retries with a new IP |

If an ad's details can't be loaded (Google blocked that request or kept failing), the ad is still delivered **for free** as `status: "partial"`, with its listing data (format, dates, image or preview link) and the reason in `errorMessage`. If Google blocks a listing halfway, the ads listed so far are delivered and a free error row says where it stopped.

### Pricing

Pay per event — **you only pay for ads delivered**, with every detail included: copy, images, video, product, countries, reach, EU data and advertiser data. Errors, partial ads (details unavailable), advertiser lookups (**Advertisers only** mode) and, with **Only new ads**, ads already seen are free. The RESIDENTIAL proxy is included in the price.

| Your Apify plan | Price per 1,000 ads |
|---|---:|
| Every plan (Free, Starter, Scale, Business…) | **$0.10** |

Plus a start fee of $0.001 per run (at the default 256 MB of memory). Example: **a competitor's last 500 ads with full copy and countries** cost about **$0.05**; a weekly monitor on 10 competitors that pays only for new ads costs a few cents a month. Other Ads Transparency scrapers charge $1–2 per 1,000 ads plus $2–3 more for the ad text or the details. Set **“Max ads in total”** or the run's maximum cost to cap spending.

### Tips

- **Most precise search:** a domain (`nike.com`) returns every ad that points to the site, including the brand's regional accounts and its agencies. A name returns the matching advertiser with the most ads.
- **Only what's running now:** set **Shown on or after** to `2 days` or filter `isActive = true`.
- **Compare competitors:** put several domains in one run and open the **Ads** view sorted by advertiser.
- **Video research:** filter **YouTube** + **Video** and use `videoUrl` to watch or transcribe the ads (pair it with our YouTube Transcript Scraper).
- **Text of older text ads:** Google archives many text ads as an image; for those you get `imageUrl`, not the words.
- **Integrations:** run it from Make, Zapier, n8n or the Apify API and send new ads to Slack, email or a sheet.

### Responsible scraping

The Actor reads the public Google Ads Transparency Center, the same pages and data anyone can open without logging in (the site has no `robots.txt` restrictions). It does not log in, does not solve CAPTCHAs or imitate a browser's fingerprint, spaces its requests per IP, and collects no personal data: advertisers are businesses and organizations that Google requires to disclose their ads.

### FAQ

**Is this the same data as the Transparency Center?** Yes: it reads the same data the website shows, with links to each ad and advertiser page so you can check.

**Why are there no impressions for my US ads?** Google publishes reach ranges, payer and audience selection only for ads shown in the EU (Digital Services Act). For other countries you get the dates and the countries where the ad ran.

**How many ads can I get?** Up to 10,000 per search, newest first; big brands have tens of thousands. Use the date and format filters to focus.

**What if I call it with an empty input?** It runs a small demo search (`nike.com`) instead of failing, so AI agents and quick API tests always get a result.

**Can I see the ad spend?** No: Google does not publish spend in the Transparency Center (except for some political ads).

**Political ads?** Not yet: this version covers the "All topics" section of the Transparency Center.

### Changelog

- **0.1** — First release: search by domain, advertiser name, ID or URL; ad copy, images, YouTube videos, Shopping products, HTML5 creatives and variations; dates, days running and still running; countries with dates and EU reach; payer, topic and EU audience selection; advertiser verification and legal name; country, platform, format and date filters; new-ad monitor; free advertiser lookup; 8 output views.

### More from Cleancut Data

- 📈 **[Google Trends Scraper](https://apify.com/cleancut/google-trends-scraper)**: interest over time, top regions and rising searches for many keywords at once. Pair it with this Actor to see which competitor campaigns follow the demand.
- 🎬 **[YouTube Transcript Scraper](https://apify.com/cleancut/youtube-transcript-scraper)**: transcripts in bulk from videos, channels, playlists and search, with SRT/VTT, AI-ready chunks, likes and publish dates. Transcribe your competitors' video ads.
- 🏨 **[Google Hotels Rate Shopper](https://apify.com/cleancut/google-hotels-price-comparator)**: what every booking site charges for your hotels and dates, with taxes, free cancellation and rate-parity gaps.
- ✈️ **[Google Flights Cheapest Fares](https://apify.com/cleancut/google-flights-cheapest-fares)**: the cheapest Google Flights fare per route and date, the cheapest day of the month and price-drop alerts.

# Actor input Schema

## `searches` (type: `array`):

Domains (nike.com), advertiser names (Shopify), advertiser IDs (AR16735076323512287233) or Transparency Center URLs (https://adstransparency.google.com/advertiser/AR…, …/creative/CR…, …?domain=nike.com). Domains are the most precise way to get a brand's ads.

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

Only ads shown in this country. "Anywhere" returns ads from every country (EU reach and audience data are filled for ads shown in the EU).

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

Only ads shown on these Google platforms. Empty = all platforms. Google can filter by platform only for ads shown since 2023-09-04.

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

Only text, image or video ads.

## `shownAfter` (type: `string`):

A date (2026-10-01) or a number of days ago ("30 days"). Empty = since 2018-05-31, the oldest date in the Transparency Center.

## `shownBefore` (type: `string`):

A date (2026-11-01) or a number of days ago ("7 days"). Empty = up to today.

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

Maximum ads per domain, advertiser or URL (up to 10,000). Large brands have tens of thousands: the Actor pages through them, newest first (4,000+ ads verified for nike.com).

## `maxTotalResults` (type: `integer`):

Stop after this many ads across all searches. 0 = no limit (the run's max cost still applies).

## `maxAdvertisersPerSearch` (type: `integer`):

When you search by name and several advertisers match (a brand and its regional accounts), how many to include, the ones with the most ads first.

## `mode` (type: `string`):

"Ads": one row per ad. "Advertisers (free)": who advertises for each search, whether they verified their identity, their country and how many ads they have; nothing is charged.

## `detailLevel` (type: `string`):

"Full" adds the ad copy (headline, description, sitelinks), YouTube video, Shopping product, countries with dates and reach, topic, payer and EU audience selection. Free: details never add to the price. "Basic" is faster and returns the listing data only (format, dates, image or preview link).

## `monitorName` (type: `string`):

Any name (e.g. "competitors-weekly"). Runs with the same name share the list of seen ads. Empty = no monitor.

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

Return (and charge) only ads not seen in previous runs of this monitor. Turns the monitor on with the name "default" if you leave the name empty.

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

Keep the default RESIDENTIAL group. Datacenter IPs are often blocked by Google on this site (BLOCKED rows).

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

How many proxy IPs work in parallel, each one at a polite pace. 6 is fast and gentle with the source.

## Actor input object example

```json
{
  "searches": [
    "nike.com",
    "Shopify",
    "AR16735076323512287233"
  ],
  "region": "anywhere",
  "platforms": [],
  "adFormat": "all",
  "maxAdsPerSearch": 20,
  "maxTotalResults": 0,
  "maxAdvertisersPerSearch": 1,
  "mode": "ads",
  "detailLevel": "full",
  "onlyNewAds": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "maxConcurrency": 6
}
```

# Actor output Schema

## `ads` (type: `string`):

All dataset items: one row per ad with preview, advertiser, format, headline, description, first and last shown, days running and a link to the Transparency Center; error rows are free and come last.

## `adCopy` (type: `string`):

Headline, description, display URL, business name, sitelinks and Shopping product of each ad.

## `media` (type: `string`):

Image, YouTube video, HTML5 creative and variations of each ad.

## `countries` (type: `string`):

One row per ad and country with the dates and the times-shown range in that country.

## `euTransparency` (type: `string`):

EU ads: who paid, Google's topic, total reach and how the audience was selected.

## `newAds` (type: `string`):

Monitor mode: ads that are new since the previous run with the same monitor name.

## `summary` (type: `string`):

JSON record with searches, ads listed and delivered, errors by code, requests, retries and duration.

# 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 = {
    "searches": [
        "nike.com"
    ],
    "maxAdsPerSearch": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cleancut/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 = {
    "searches": ["nike.com"],
    "maxAdsPerSearch": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("cleancut/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 '{
  "searches": [
    "nike.com"
  ],
  "maxAdsPerSearch": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call cleancut/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

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