# Google Ads Transparency Scraper — Competitor Ads (`adorable_partial/google-ads-transparency-scraper`) Actor

Get every ad a brand or domain runs on Google Search, YouTube, Maps, Play and Shopping from the Ads Transparency Center: ad copy, images, videos, first and last shown dates, landing pages with UTM tags. Bulk check which domains advertise. No login.

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

## Pricing

from $1.05 / 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.
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, Ad Copy & Landing Pages

See **every ad a brand runs on Google**: Search, YouTube, Display, Maps, Play and Shopping, straight from the public **Google Ads Transparency Center**. Search by **brand name, domain or advertiser ID** and get each ad with its **format, first and last date shown, days running, image or video, ad copy, display URL and landing page with UTM tags**. Check long lists of domains in bulk to find out **who advertises on Google** and how much.

No login, no Google account, no API key.

![Nubank search ads as Google archives them (images) next to the display URL, headline and description this Actor extracts as text](https://api.apify.com/v2/key-value-stores/w9XdyR70ev89zKnzR/records/demo.png?signature=dxHYlQs7KIVFPU8lOHGY)

*Real output of this Actor for "Nubank" in Brazil: Google stores search ads as pictures, the Actor returns them as text.*

### Why use it

- 📝 **Real ad copy, also for text ads**: Google archives search ads as *images*. This Actor reads them (OCR) and returns **display URL, headline and description as text**, including dynamic keyword insertion such as `{KeyWord:Nike Shoes}`. Other scrapers only give you the picture.
- 🎯 **Landing pages and UTM tags**: see where each ad sends traffic and how the campaign is tagged (`utm_source`, `utm_campaign`…), when Google exposes the click URL.
- 🎬 **YouTube videos**: video ads come with their YouTube link and thumbnail.
- 📍 **Local and Maps ads**: business name, call to action, category and the store addresses shown in the ad.
- 🔎 **Search the way you think**: brand names ("Magazine Luiza"), domains (nike.com), advertiser IDs or Transparency Center URLs, mixed in one list.
- ✅ **Bulk advertiser check**: one row per domain or brand: does it advertise on Google, how many ads, which accounts, when the last ad ran. Great for lead lists.
- 🌍 **Filters**: country, platform (Search, YouTube, Maps, Play, Shopping), format (text, image, video) and date range, applied by Google itself, so you only pay for what you need.
- 💸 **Pay per ad**: no subscription, no per-seat SpyFu or Semrush plan.

### Who uses it

| Who | What for |
|---|---|
| **Marketing & growth teams** | Monitor competitors' messages, offers and creatives over time |
| **Agencies** | Competitive audits and pitch decks for new clients in minutes |
| **SEO / SEM specialists** | Find the keywords, headlines and landing pages competitors invest in |
| **Sales & lead generation** | Find companies that spend on Google Ads (bulk domain check) |
| **E-commerce & brands** | Spot resellers or affiliates bidding on your brand |
| **Researchers & journalists** | Study advertising by sector, country or period |

### Input

| Field | Default | Description |
|---|---|---|
| **Advertisers, domains or URLs** (`searchTerms`) | — | Brand names, domains, advertiser IDs (`AR…`) or Ads Transparency Center links |
| **What to get** (`mode`) | `ads` | `ads` = every ad with details; `advertisers` = one row per search (does it advertise, how many ads) |
| **Country** (`region`) | `anywhere` | 2-letter code (BR, US, GB, DE, IN…) |
| **Max ads per advertiser or domain** (`maxAdsPerSearch`) | `100` | Most recently shown first |
| **Ad format** (`adFormat`) | `all` | `text`, `image` or `video` |
| **Google platform** (`platform`) | `all` | `search`, `youtube`, `maps`, `play`, `shopping` (ads shown since Sept 2023) |
| **Only ads shown in the last N days** (`shownInLastDays`) | — | e.g. 30 |
| **Shown from / until** (`startDate`, `endDate`) | — | Exact date range (YYYY-MM-DD) |
| **Advertiser accounts per brand name** (`maxAdvertisersPerName`) | `3` | A brand often has several accounts; the biggest ones are used |
| **Ad copy and landing pages** (`includeAdDetails`) | `true` | Read headline, description, display URL, landing page and YouTube video from each ad preview |
| **Read text ads (OCR)** (`readTextAds`) | `true` | Turn the text-ad images into text |
| **Proxy** (`proxyConfiguration`) | Apify Proxy | Google limits requests per IP; IPs are rotated automatically |

```json
{
  "searchTerms": ["nike.com", "Magazine Luiza", "AR14248386603834671105"],
  "region": "BR",
  "maxAdsPerSearch": 200,
  "shownInLastDays": 30
}
```

### Output

One row per ad (`ads` mode):

```json
{
  "searchTerm": "Nubank",
  "advertiserId": "AR16872622891684855809",
  "advertiserName": "NU PAGAMENTOS S.A. INSTITUIÇÃO DE PAGAMENTO",
  "domain": "nubank.com.br",
  "creativeId": "CR11535416222929649665",
  "format": "text",
  "firstShown": "2023-06-22T20:02:34Z",
  "lastShown": "2026-10-12T16:09:27Z",
  "daysShown": 1209,
  "visibleUrl": "www.nubank.com.br/investimento",
  "headline": "Invista mais fácil com Nubank - Rende até 120% do CDI",
  "description": "No Nubank é você quem tem o controle do seu dinheiro. Parece simples. E é. Caixinha Turbo: rende...",
  "imageUrl": "https://tpc.googlesyndication.com/archive/simgad/4636736067623573836",
  "adUrl": "https://adstransparency.google.com/advertiser/AR16872622891684855809/creative/CR11535416222929649665?region=BR",
  "adsTotalMin": 1000,
  "adsTotalMax": 2000
}
```

Depending on the ad, you also get:

| Field | When |
|---|---|
| `landingUrl`, `utm` | The ad's click URL is available (often video ads) |
| `youtubeVideoUrl`, `videoThumbnailUrl`, `videoDurationSeconds` | YouTube / video ads |
| `businessName`, `callToAction`, `businessCategory`, `locations` | Maps and local ads |
| `adText` | Full OCR text of a text ad |
| `adsTotalMin`, `adsTotalMax` | How many ads Google reports for this advertiser or domain in total |

`advertisers` mode returns one row per search: `found`, `adsMin`, `adsMax`, `lastAdShown`, `formats`, `advertisers` (accounts) and a link to the Transparency Center.

### Pricing

Pay per **ad scraped** (details and OCR included) or per **advertiser checked** in bulk-check mode, plus a tiny start fee. No subscription. Apify plan discounts apply automatically (see the **Pricing** tab). Use **Max ads** or the run's *maximum cost* to cap spending.

### Use it from code or an AI agent

**Python: the competitor's newest ads**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("adorable_partial/google-ads-transparency-scraper").call(run_input={
    "searchTerms": ["competitor.com"], "region": "US", "shownInLastDays": 30,
})
for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(ad.get("format"), ad.get("lastShown"), ad.get("headline"), ad.get("landingUrl"))
```

**JavaScript: which of my leads advertise on Google?**

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('adorable_partial/google-ads-transparency-scraper').call({
    searchTerms: ['acme.com', 'example.org', 'shop.example'],
    mode: 'advertisers',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.filter((r) => r.found).forEach((r) => console.log(r.searchTerm, r.adsMin, r.lastAdShown));
```

**No-code and agents:** schedule a weekly competitor report with **Make**, **Zapier** or **n8n**, send new ads to Slack or Google Sheets, or let an AI agent research advertisers through the **Apify MCP server**.

### FAQ

**Is this data public?** Yes. Google publishes it in the Ads Transparency Center for anyone to see; this Actor collects it for you. It is not affiliated with Google.

**Why don't all ads have a headline or landing page?** Google shows different previews per ad type. Text ads are read with OCR; video, Maps and local ads come with their copy and links when Google includes them; some display ads are only an image (`imageUrl`).

**Why "adsTotalMin / adsTotalMax"?** Google reports totals as ranges (e.g. 9,000–10,000).

**Can I see spend, impressions or targeting?** Google only publishes those for political ads and some regions; this Actor returns what the Transparency Center shows for each ad.

**I got a blocking error.** Google limits requests per IP. The Actor rotates Apify Proxy IPs automatically; for very large runs choose residential proxies in the Proxy field.

### Related Actors

- [Website Screenshot](https://apify.com/adorable_partial/website-screenshot) — capture the landing pages of competitors' ads
- [Audio & Video to Text (Whisper)](https://apify.com/adorable_partial/whisper-audio-video-transcriber) — transcribe video ads
- [Video Frame Extractor for AI](https://apify.com/adorable_partial/video-frame-extractor-ai) — key frames from video creatives

### Need a different tool? Request it

Missing a feature, an input or output format, or a whole different tool for your workflow? **Open an issue in the Issues tab** and describe what you need:

- what goes in (files, URLs, data) and what should come out,
- roughly how much you process (per day or month),
- one example, if you can share it.

Requests with a real use case get built, either as a new option in this Actor or as a new Actor in [this collection](https://apify.com/adorable_partial), and you get notified in the issue when it's live. Every request is read.

# Actor input Schema

## `searchTerms` (type: `array`):

Brand or company names (e.g. Nike), domains (e.g. nike.com), advertiser IDs (AR…) or Ads Transparency Center URLs. One per line.

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

Ads: every ad with its details. Advertiser check: one row per search with whether it advertises on Google, the number of ads and its advertiser accounts (fast and cheap for long domain lists).

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

2-letter country code where the ads were shown (BR, US, GB, DE, IN…) or "anywhere".

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

Newest ads first. Big brands have tens of thousands of ads.

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

Only text, image or video ads.

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

Only ads shown since September 2023 can be filtered by platform.

## `shownInLastDays` (type: `integer`):

Leave empty for all ads. 30 = ads that ran in the last month.

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

Only ads shown on or after this date (YYYY-MM-DD). Overrides "last N days".

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

Only ads shown on or before this date (YYYY-MM-DD). Default: today.

## `maxAdvertisersPerName` (type: `integer`):

A brand name can match several advertiser accounts; the ones with most ads are used.

## `includeAdDetails` (type: `boolean`):

Read headline, description, display URL, landing page (with UTM tags) and video length from each ad's preview, when Google provides one.

## `readTextAds` (type: `boolean`):

Google archives search text ads as images. Read them and return display URL, headline and description as text (including dynamic keyword insertion like {KeyWord:…}).

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

Google limits requests per IP; Apify Proxy rotates IPs automatically. Use residential proxies if you see blocking errors.

## Actor input object example

```json
{
  "searchTerms": [
    "nike.com",
    "Magazine Luiza"
  ],
  "mode": "ads",
  "region": "anywhere",
  "maxAdsPerSearch": 100,
  "adFormat": "all",
  "platform": "all",
  "maxAdvertisersPerName": 3,
  "includeAdDetails": true,
  "readTextAds": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One row per ad: advertiser, format, dates, ad copy, display URL, landing page, image or YouTube video.

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

In advertiser-check mode: one row per domain or brand with the number of ads and accounts.

# 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 = {
    "searchTerms": [
        "nike.com",
        "Magazine Luiza"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("adorable_partial/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 = { "searchTerms": [
        "nike.com",
        "Magazine Luiza",
    ] }

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

```

## MCP server setup

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