# Google Ads Transparency Scraper & New Ads Monitor (`ivan-petrus-g/google-ads-transparency-monitor`) Actor

Track competitors' Google ads from the Google Ads Transparency Center. Monitor domains, advertiser IDs or names by country, get ONLY NEW ads since the last run, plus a summary per advertiser. Text, image & video ads, first/last shown dates, regions, video IDs and ad copy.

- **URL**: https://apify.com/ivan-petrus-g/google-ads-transparency-monitor.md
- **Developed by:** [Ivan Petrus](https://apify.com/ivan-petrus-g) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 ads

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 Scraper & New Ads Monitor (Search, Display, YouTube)

**Google Ads Transparency Center scraper and competitor ad monitor.** Give it competitor **domains**, **advertiser IDs** or **advertiser names**. It returns every ad Google has shown for them in any country, including format, first/last shown dates, days running, image or preview URL, YouTube video ID, and ad copy where available. With **"Only new ads"** turned on, each scheduled run outputs **only the ads that appeared since the last run**, so it works as a daily competitor-ads alert feed.

Built for **reliability**: retries with exponential backoff, HTTP 429 handling, proxy session rotation, clear error rows and a free summary row per competitor. **Failed checks are never charged.**

### Sample output

One ad row from a real Apify cloud run (Oct 2026, domain `zappos.com`, region US). Each target also gets a free summary row:

```json
{
  "type": "ad",
  "target": "zappos.com",
  "region": "US",
  "advertiserName": "Zappos IP, Inc.",
  "creativeId": "CR11795179083397070849",
  "format": "text",
  "firstShown": "2026-04-02T18:12:14+00:00",
  "lastShown": "2026-10-07T18:48:08+00:00",
  "daysRunning": 189,
  "transparencyUrl": "https://adstransparency.google.com/advertiser/AR04821233212191670273/creative/CR11795179083397070849",
  "isNew": true
}
```

### What you get

| Data | Details |
|---|---|
| 🆕 New-ads diff | Remembers what it has seen (named key-value store) and outputs only new ads on later runs. Each ad row has `isNew`. |
| 🧾 Ad details | Advertiser name + ID, creative ID, format (text / image / video), first shown, last shown, days running, target domain |
| 🖼️ Creative | Image URL, or the rendered-preview URL, plus a direct `transparencyUrl` link to the ad in Google's Transparency Center |
| ▶️ Video ads | YouTube `videoId` + `youtubeUrl` (with "Extract ad content") |
| ✍️ Ad copy | Headline, description and other text snippets when Google exposes them as text (with "Extract ad content") |
| 🌍 Where it ran | Per-country first/last shown dates and impression ranges, variations count, verified legal name (with "Enrich details") |
| 📊 Summary row | Per competitor and region: total ads estimate, ads fetched, **new ads since last run**, format mix, newest/oldest ad, active in the last 24 h |

Filters: **region** (any country, or `anywhere`), **format** (text, image, video), **date range** (`lastDays`, or `dateFrom`/`dateTo`), and a maximum number of ads per competitor.

### Use cases

- **Daily competitor ad alerts:** schedule it every morning and get only the new ads (email, Slack, Sheets, webhooks).
- **PPC and creative research:** see which messages, offers and videos competitors are testing, and for how long.
- **Agencies:** monitor dozens of client competitors across countries in one run.
- **Market entry:** check who is advertising in a country before you launch there.
- **Brand protection:** spot advertisers bidding on your brand or impersonating your domain.

### Input examples

**Daily monitor of competitors (new ads only):**

```json
{ "domains": ["zappos.com", "nike.com"], "regions": ["US"], "onlyNewAds": true }
```

**Advertiser by name, all countries, video ads with YouTube IDs:**

```json
{ "advertiserNames": ["Canva"], "advertiserNameMatch": "allSimilar", "regions": ["anywhere"], "formats": ["video"], "extractAdContent": true }
```

**Ads first shown in the last 7 days in Germany and the UK, with details:**

```json
{ "domains": ["hubspot.com"], "regions": ["DE", "GB"], "lastDays": 7, "enrichDetails": true }
```

**Start monitoring silently (record existing ads, output nothing on the first run):**

```json
{ "domains": ["rozetka.com.ua"], "regions": ["UA"], "firstRunBehavior": "baselineOnly", "stateStoreName": "my-ua-monitor" }
```

### Output example

**Ad row:**

```json
{
  "type": "ad",
  "target": "shopify.com",
  "region": "GB",
  "advertiserId": "AR01625195283841286145",
  "advertiserName": "Shopify Inc.",
  "creativeId": "CR07882013145693159425",
  "format": "video",
  "firstShown": "2026-07-22T21:13:26+00:00",
  "lastShown": "2026-10-07T18:34:51+00:00",
  "daysRunning": 77,
  "targetDomain": "shopify.com",
  "videoId": "1mMdQ6CJio4",
  "youtubeUrl": "https://www.youtube.com/watch?v=1mMdQ6CJio4",
  "transparencyUrl": "https://adstransparency.google.com/advertiser/AR01625195283841286145/creative/CR07882013145693159425",
  "isNew": true
}
```

**Ad copy (text ad, with "Extract ad content"):** `"adTextHeadline": "Bags & Backpacks", "adTextDescription": "Discover {KeyWord} Online At Nike.com. Shop The Official Nike Site."`

**Summary row (free):**

```json
{ "type": "summary", "target": "zappos.com", "region": "US", "totalAdsEstimate": "2000-3000", "adsFetched": 50, "newAdsSinceLastRun": 0, "formats": { "image": 20, "text": 20, "video": 10 }, "newestAdFirstShown": "2026-09-30T11:13:27+00:00" }
```

Failed checks appear as `{ "type": "error", "status": "failed", "error": "...", "hint": "..." }` and are **not charged**.

### Pricing (pay per event)

- **$0.005 per competitor checked** (one domain / advertiser in one region, summary row included)
- **$1 per 1,000 ads** output. With "Only new ads" on, you pay only for new ads.
- A tiny $0.001 start fee per run. No proxy or compute costs on top.
- Example: monitoring 20 competitors daily with ~5 new ads each costs about **$0.20 per day**.

Set **Max ads per competitor** or a maximum cost per run to cap spending. The actor stops gracefully, and ads that were not delivered are **not** marked as seen, so you get them next time.

### Reliability notes

- **Proxy:** Apify Proxy is on by default. On HTTP 429 or a block, the run rotates the proxy session and backs off exponentially (`maxRetries`).
- **State:** "seen" ads are stored per competitor + region + format filter in the named key-value store `stateStoreName`. Use different names for different monitors. Up to 20,000 IDs are kept per monitor.
- **Advertiser names:** `best` picks the exact (or closest) match. `allSimilar` checks up to 5 matching advertiser accounts (e.g. one brand with several country accounts). Advertiser IDs (`AR…`) are the most precise.
- **Health check:** schedule `tests/selftest_input.json` daily with a run-failure email alert.

### Daily alerts to Slack or email

1. Fill in the input and click **Save as a new task** (one task per client or competitor set is a good pattern).
2. In **Schedules**, create a schedule (for example every day at 08:00 in your time zone) and add the task.
3. In the task's **Integrations** tab, add the **Slack** or **Gmail** integration to get a message when a run finishes,
   or a **webhook** on "Run succeeded" that passes the run to Zapier, Make, n8n or your own endpoint. Those tools can read the rows from
   `https://api.apify.com/v2/datasets/{defaultDatasetId}/items` and format them however you like.

Because monitor mode outputs **only the ads that appeared since the previous run**, every scheduled run's dataset *is* your alert list. An empty dataset (apart from free summary rows) means nothing changed.
Turn on Apify's run-failure notifications too, so you hear about a failed run instead of silence.

### Related actors

Part of a small **competitor-intelligence suite** by the same developer. Same conventions everywhere: pay per event, failed items are never charged, and the monitors return only what changed since the last run.

- [Google Trends Scraper & API](https://apify.com/ivan-petrus-g/google-trends-api): interest over time, by region/city, top queries and Trending now for any country.
- [LinkedIn Ad Library Scraper & New Ads Monitor](https://apify.com/ivan-petrus-g/linkedin-ad-library-monitor): competitors' LinkedIn ads without login, incl. EU impressions and targeting.
- [Bing Ads Library Scraper - Microsoft Ads Monitor (EU)](https://apify.com/ivan-petrus-g/microsoft-ads-library-monitor): Bing ads from Microsoft's official Ad Library (EU/EEA), with impressions by country.
- [ATS Jobs Scraper & Hiring Monitor](https://apify.com/ivan-petrus-g/company-hiring-monitor): new and closed jobs from Greenhouse, Lever, Ashby, Workday and 6 more job boards, by company domain.
- [App Store & Google Play Scraper](https://apify.com/ivan-petrus-g/app-store-monitor): ratings, installs, versions, chart and keyword ranks of iOS and Android apps, with change rows.

### FAQ

**What is the Google Ads Transparency Center?** It is Google's public library of ads shown on Search, YouTube, Display and Shopping, with the verified advertiser behind each one. This actor reads the same data the website shows and returns it as structured JSON/CSV/Excel.

**How do I find an advertiser ID?** Open the advertiser on adstransparency.google.com. The `AR…` part of the URL is the ID. Or just enter the advertiser name or website domain.

**Why are some text ads returned as images?** Google archives many Search ads as rendered images. For those, you get `imageUrl`. Ad copy is extracted when Google provides it as text (typically local/Search ads with a preview, and Shopping product titles).

**Does it show ad spend or clicks?** No. Google does not publish spend for commercial ads. With "Enrich details" you get per-country impression ranges where Google shows them.

**Can I get alerts?** Yes. Schedule the actor and connect the dataset to email, Slack, Google Sheets, Zapier, Make or n8n. With "Only new ads", every run's dataset is your list of new ads.

**Is it legal?** It collects public ad-library data published by Google for transparency. You are responsible for complying with Google's Terms of Service and local law.

*Keywords: google ads transparency center scraper, google ads library, competitor ads monitor, new ads alert, ad spy tool, youtube ads scraper, search ads scraper, ppc competitor research, google ad library api.*

# Actor input Schema

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

Websites whose Google ads you want to track, e.g. nike.com. URLs are accepted and cleaned automatically.

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

Google Ads Transparency advertiser IDs (start with AR...), copied from the advertiser page URL.

## `advertiserNames` (type: `array`):

Legal advertiser names, e.g. 'Nike, Inc.'. Resolved to advertiser IDs automatically (exact match preferred).

## `advertiserNameMatch` (type: `string`):

best = exact match or the top suggestion. allSimilar = up to 5 advertisers whose name contains the text.

## `regions` (type: `array`):

2-letter country codes where the ads were shown (US, GB, DE, UA...). Use 'anywhere' for all regions. Each target is checked once per region.

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

Only these formats (empty = all).

## `lastDays` (type: `integer`):

Only ads shown within the last N days. Overrides dateFrom/dateTo.

## `dateFrom` (type: `string`):

YYYY-MM-DD. Ads shown on or after this date.

## `dateTo` (type: `string`):

YYYY-MM-DD. Defaults to today when dateFrom is set.

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

Remember which ads were already seen (in a named key-value store) and output only new ones. Perfect for daily schedules.

## `firstRunBehavior` (type: `string`):

outputAll = the first run returns all current ads (up to the limit). baselineOnly = the first run only records current ads; later runs return what's new (cheaper).

## `stateStoreName` (type: `string`):

Named key-value store that keeps seen ad IDs. Use different names for independent monitors.

## `maxAdsPerTarget` (type: `integer`):

Newest ads first. 0 = all ads (can be thousands for big brands).

## `enrichDetails` (type: `boolean`):

One extra request per ad: regions where it ran (with first/last shown dates and impression ranges), number of variations, all variation images.

## `extractAdContent` (type: `boolean`):

One extra request per text/video ad: YouTube video ID + URL, and text ad headline/description when Google exposes them (best effort; some text ads are only available as images).

## `includeSummary` (type: `boolean`):

Adds one free summary row per target and region: estimated total ads, new ads, formats, advertisers, newest ad date.

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

Parallel checks.

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

Retries with backoff and proxy rotation on 429/5xx/network errors.

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

Apify Proxy (datacenter) is enough in our tests and keeps runs fast.

## Actor input object example

```json
{
  "domains": [
    "zappos.com"
  ],
  "advertiserNameMatch": "best",
  "regions": [
    "US"
  ],
  "onlyNewAds": true,
  "firstRunBehavior": "outputAll",
  "stateStoreName": "ads-monitor-state",
  "maxAdsPerTarget": 10,
  "enrichDetails": false,
  "extractAdContent": false,
  "includeSummary": true,
  "maxConcurrency": 3,
  "maxRetries": 6,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

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

No description

## `runSummary` (type: `string`):

No description

# 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 = {
    "domains": [
        "zappos.com"
    ],
    "regions": [
        "US"
    ],
    "maxAdsPerTarget": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ivan-petrus-g/google-ads-transparency-monitor").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 = {
    "domains": ["zappos.com"],
    "regions": ["US"],
    "maxAdsPerTarget": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("ivan-petrus-g/google-ads-transparency-monitor").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 '{
  "domains": [
    "zappos.com"
  ],
  "regions": [
    "US"
  ],
  "maxAdsPerTarget": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call ivan-petrus-g/google-ads-transparency-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ivan-petrus-g/google-ads-transparency-monitor"
        }
    }
}
```

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/X29lgasGQ20ekhO02/builds/krhHPVAfdkQQiDk2v/openapi.json
