# Google Ads Transparency Monitor: New Ad Alerts (`magnova/google-ads-transparency-monitor`) Actor

New ads from Google's Ads Transparency Center for any advertiser — creative ID, format, first/last shown dates, days shown and the ad creative itself. Monitor mode delivers only ads that are new since your last run. $0.01 per new ad, no start fee, runs with no new ads are free.

- **URL**: https://apify.com/magnova/google-ads-transparency-monitor.md
- **Developed by:** [Magnova](https://apify.com/magnova) (community)
- **Categories:** Business, Automation, Marketing
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.00 / 1,000 new ad fetcheds

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 Monitor: New Ad Alerts

**Get every new Google ad your competitors launch — as clean structured data, the moment it appears in Google's Ads Transparency Center — and pay only for the ads that are actually new.**

You give this Actor a list of advertisers to watch in Google's Ads Transparency Center: competitors, agency clients, or your own brands. On every run it checks each advertiser's current ads and delivers **only the ads no earlier run has seen**: creative ID, format, first-shown and last-shown dates, how many days the ad was shown, and the ad creative itself (its archived image or preview link). Schedule it daily and it becomes a quiet new-ad alert feed for your whole competitive set — no more clicking through the Transparency Center by hand, and no paying for the same ads twice.

Snapshot scrapers dump an advertiser's entire current ad library on every run and charge you for all of it, every time. This monitor is built the other way: it remembers what it has already delivered and sends you only the delta.

### What it does

- **Monitors any advertiser in the Ads Transparency Center** — competitors, clients, your own accounts. If Google discloses their ads, this Actor can watch them.
- **Delta-only delivery.** With a monitor state store attached, each run delivers only genuinely new ads. A day with no new ads produces an empty result and costs nothing.
- **Complete ad records.** Advertiser name as Google publishes it, creative ID, format (text / image / video, with Google's raw format code preserved), first-shown and last-shown dates, the number of days the ad was shown, the ad's own creative preview, and a deep link to the ad in the Transparency Center.
- **Per-advertiser resilience.** If one advertiser fails (a bad entry, an ambiguous name), that advertiser produces one ERROR record and the rest of the run continues. If Google rate-limits the run, affected advertisers produce BLOCKED records and — critically — their monitor state is **not** advanced, so the next run catches them up instead of silently losing a day of ads. The final SUMMARY record tells you exactly what happened per category.
- **Gentle by design.** One advertiser at a time, paced requests, no login, no API key, no proxies, no cookies.

### How monitoring works

1. **First run.** Without a store — or the first time an advertiser is seen — the run delivers the advertiser's current ads as a *baseline batch* (charged normally), so you start with data, not an empty feed. Prefer to start silently? Turn on **Start monitoring silently** (`monitorOnlyNew`) and the first run only remembers the current ads; delivery starts with the next new ad.
2. **Attach a store.** Pick any of your Apify key-value stores in the **Monitor state store** input. The Actor keeps one small record in it: which creative IDs it has already seen for each advertiser.
3. **Schedule it.** Run it daily (or weekly, with a bigger window) with the same store. Every run fetches each advertiser's current ads — the window size is yours to set — diffs them against the store, delivers only the new ones, and updates the store.
4. **Size the window to your schedule.** Only ads inside the checked window can be detected as new. The default window of 40 ads per advertiser comfortably covers a daily check of most advertisers. For a weekly check of a very active advertiser, raise it (up to 200).

### Inputs

| Input | Type | Description |
| --- | --- | --- |
| `advertisers` | array of strings (required) | The advertisers to monitor. Each entry can be an **AR advertiser ID** (e.g. `AR12815412684405080065`), the advertiser's **Ads Transparency Center URL** (a creative URL works too — its advertiser is monitored), or a **name/domain** to resolve by search. IDs and URLs are strongly recommended: name search is only an assist (see the FAQ). Up to 50 advertisers per run. |
| `adsPerAdvertiser` | integer, 10–200 (default 40) | How many of each advertiser's current ads are fetched and diffed per run. Checking is free; you pay only for new ads delivered. |
| `monitorOnlyNew` | boolean (default false) | When true, the first run for an advertiser silently remembers its current ads instead of delivering a baseline batch. Only ads launched afterwards are ever delivered. |
| `monitorStore` | key-value store (optional) | The store that remembers seen ads across runs — this is what makes only-new delivery work. Without it, every run is a full baseline run. |
| `maxTotalChargeUsd` | number (optional) | Hard stop for the run's charges; the SUMMARY reports `stoppedByMaxCharge` when it fires. Undelivered new ads stay unseen, so the next run delivers them. |

### Outputs

Every run writes four kinds of records to the dataset:

**`NEW_AD` records — one per new ad (the charged records):**

| Field | Meaning |
| --- | --- |
| `advertiserName` / `advertiserId` | The advertiser's business name, exactly as Google publishes it, and its AR ID |
| `creativeId` | The ad's unique CR creative ID |
| `adFormat` / `formatCode` | The ad's format — `text`, `image`, or `video` — from Google's own format classification, plus Google's raw numeric format code |
| `firstShown` / `lastShown` | The first and most recent dates Google shows the ad as having been shown (ISO dates) |
| `daysShown` | The number of days Google reports the ad as having been shown, counted across its first–last shown window (an ad that did not run every day shows fewer days than the window spans) |
| `adImageUrl` / `adPreviewUrl` | The creative itself: Google's archived image of the ad when it has one (for text ads, a rendered snapshot of the ad — its full wording is visible in the image), and Google's preview link for creatives served through its preview renderer (video and rich-media creatives) |
| `transparencyUrl` | Deep link to this ad in the Ads Transparency Center |

**`ERROR` records** — one per advertiser that could not be checked (never charged), with the reason. An ambiguous name produces an ERROR record whose `candidates` list shows the advertisers Google suggested (AR ID, name, country, ad-count hint), so you can re-run with the exact AR ID.

**`BLOCKED` records** — one per advertiser Google rate-limited in this run (never charged). Nothing was fetched for them and their monitor state was left untouched; they are caught up automatically on the next run.

**One `SUMMARY` record** at the end of every run (never charged): per-category counts (advertisers checked / fetched OK / empty / blocked / errored, ads fetched, new ads delivered, duplicates skipped, silently seeded), any name-resolution warnings, whether a state store was used, and whether the run stopped at your maximum charge or the platform timeout.

### Pricing

**$0.01 per new ad delivered.** No start fee, no per-run fee, no charge for checking. Volume tiers apply automatically: SILVER pays $0.0085 per new ad, GOLD and above $0.007.

- Already-seen ads: **free** (skipped as duplicates).
- Silently seeded ads (`monitorOnlyNew`): **free**.
- ERROR and BLOCKED records, and the SUMMARY: **free**.
- A run that finds no new ads costs **$0**.

Compare that with snapshot scrapers, which charge for an advertiser's *entire* current library on every run — a daily snapshot of a 500-ad competitor costs 50–500× more per month than monitoring it here, where a typical day delivers a handful of genuinely new ads.

### Use cases

- **Competitor ad alerts.** Watch your top competitors and get each new creative the day it launches — new product angles and new offers — without refreshing the Transparency Center by hand.
- **Agency client monitoring.** Track every client's competitors in one scheduled run; the SUMMARY tells you which advertisers were checked, blocked or errored, so the feed is auditable.
- **Brand protection.** Watch your own brands and resellers: new ads from namesake or reseller advertisers surface immediately, with the creative itself attached.
- **Creative research.** Build a clean, deduplicated stream of new ads in your niche (creative, format, run dates, days shown) for swipe files and trend analysis.

### For AI agents and MCP

This Actor is designed to be driven by AI agents via the Apify MCP server. Inputs are minimal and self-describing: `advertisers` accepts AR IDs, Transparency Center URLs, or names (resolution outcomes are reported, never silent). Outputs are one flat record per new ad with stable IDs (`advertiserId`, `creativeId`) suitable for deduplication, alerting and downstream joins, plus a machine-readable SUMMARY record with counts, warnings and stop reasons (`stoppedByMaxCharge`, `blockedAdvertisers`). A typical agent workflow: run once with a `monitorStore` and `monitorOnlyNew: true` to seed, then schedule daily runs against the same store and forward only runs whose SUMMARY reports `deliveredNew > 0`.

### Google Ads Transparency API

There is no official API for the Ads Transparency Center. This Actor reads the same public registry the Transparency Center website shows to any logged-out visitor, through the site's own public data calls — no login, no account, no API key, no cookies. Because the underlying registry is Google's, its layout can change; the monitor is checked weekly and its per-advertiser error reporting is designed to surface breakage loudly instead of returning silent empty results.

### Legal and data

Google's Ads Transparency Center is a public disclosure system: Google publishes it so that anyone — regulators, journalists, competitors, the public — can see which ads a verified advertiser is running. This Actor reads only what that public registry shows to logged-out visitors. It collects **business-level disclosure data only**: advertiser names exactly as Google publishes them, and the ads themselves. It collects no personal data, uses no login or account, bypasses no access control, and sets no cookies. Advertiser and ad data remains Google's published disclosure; respect Google's terms and your local law when reusing it.

### FAQ

**Should I use AR IDs, URLs, or names?** IDs or URLs. Name search resolves through Google's suggestions, which are won by regional namesakes — "Nike" first matches a Kenyan entity with one ad, not Nike, Inc. When a name *is* resolved, the SUMMARY carries a warning naming the AR ID it resolved to; when a name matches several advertisers, you get an ERROR record with the candidate AR IDs instead of a guess. Find an advertiser's AR ID in its Transparency Center URL.

**Why did an advertiser come back BLOCKED?** Google throttles the registry per network address, and shared platform addresses occasionally start a run already throttled — so yes, a run can come back with BLOCKED records instead of ads for some or all advertisers. Nothing is lost and nothing is charged: BLOCKED records are always free, the advertiser's monitor state is not advanced, and the next run catches it up automatically. If your very first (baseline) run comes back blocked, simply run it again — a fresh run uses a new network address and usually succeeds, and retrying can never skip or double-deliver an ad.

**Where are the ad's text and the advertiser's domain?** Google's registry does not publish them as data in its ad listings, so this Actor does not invent them. A text ad's full wording *is* visible — inside its archived snapshot image (`adImageUrl`), which is how the Transparency Center itself presents it. The registry's listings carry no machine-readable ad copy and no advertiser domain field; tools that print a domain are guessing it from the advertiser's name. Every field this Actor ships is a field the registry actually contains.

**Can I filter by region?** No — and be wary of tools that claim to: Google's registry serves the same global ("anywhere") creative set regardless of the region requested; it does not narrow results server-side. This Actor does not offer a filter that would silently do nothing.

**How is this different from an Ads Transparency scraper?** A scraper returns an advertiser's whole current library per run (and charges for all of it, every run). This monitor returns only the ads that are new since your last run — which is what alerting, tracking and research workflows actually consume — and charges only for those.

**What counts as "new"?** A creative ID the monitor has never delivered (or seeded) for that advertiser, inside the checked window. If an advertiser launches more ads between runs than your window covers, raise `adsPerAdvertiser`.

# Actor input Schema

## `adsPerAdvertiser` (type: `integer`):

How many of each advertiser's current ads are fetched and compared against the monitor store on every run (the diffing window). Only ads inside this window can be detected as new, so size it above the most ads an advertiser could launch between two runs: 40 suits daily checks of most advertisers; raise it (up to 200) for weekly checks of very active advertisers. Checking itself is free — you only pay for new ads actually delivered.

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

The advertisers to watch in Google's Ads Transparency Center — your competitors, your clients, or your own brands. Give each advertiser in ONE of these forms (AR ID or URL is best): (1) its AR advertiser ID, e.g. "AR12815412684405080065" (Amazon US); (2) its Ads Transparency Center URL, e.g. "https://adstransparency.google.com/advertiser/AR12815412684405080065" (a creative URL works too — its advertiser is monitored); (3) a name or domain, which is resolved by search. Name search is only an assist: regional namesakes are common ("Nike" first matches a Kenyan namesake), so a resolved name is reported as a warning in the run SUMMARY, and a name with several plausible matches produces an ERROR record listing the candidate AR IDs instead of guessing. Up to 50 advertisers per run.

## `maxTotalChargeUsd` (type: `number`):

Optional hard stop for this run's charges: delivery stops as soon as the charged ads reach this amount (checked conservatively at the highest per-ad price, so the run may stop slightly early on discounted tiers), and the SUMMARY record reports stoppedByMaxCharge. Leave empty for no cap. The run-level maximum charge in the run options is also honoured exactly.

## `monitorOnlyNew` (type: `boolean`):

Off (default): the first run for an advertiser delivers its current ads as a baseline batch (charged), later runs deliver only new ones. On: the first run silently remembers the current ads without delivering or charging anything, and only ads launched afterwards are ever delivered. Only applies when a monitor store is selected; without a store every run is a baseline run.

## `monitorStore` (type: `string`):

A key-value store this Actor may read and write to remember which ads it has already seen for each advertiser — this is what makes only-new delivery work across runs. Pick any store you own; the Actor keeps one small state record in it. Without a store, every run delivers all checked ads as a NEW baseline and remembers nothing. If the store is missing or cannot be opened, the run continues in baseline mode and the SUMMARY record says so — it never crashes.

## Actor input object example

```json
{
  "adsPerAdvertiser": 40,
  "advertisers": [
    "AR12815412684405080065",
    "AR04119126533128323073"
  ],
  "maxTotalChargeUsd": 1,
  "monitorOnlyNew": false
}
```

# Actor output Schema

## `results` (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 = {
    "adsPerAdvertiser": 40,
    "advertisers": [
        "AR12815412684405080065",
        "AR04119126533128323073"
    ],
    "monitorOnlyNew": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("magnova/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 = {
    "adsPerAdvertiser": 40,
    "advertisers": [
        "AR12815412684405080065",
        "AR04119126533128323073",
    ],
    "monitorOnlyNew": False,
}

# Run the Actor and wait for it to finish
run = client.actor("magnova/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 '{
  "adsPerAdvertiser": 40,
  "advertisers": [
    "AR12815412684405080065",
    "AR04119126533128323073"
  ],
  "monitorOnlyNew": false
}' |
apify call magnova/google-ads-transparency-monitor --silent --output-dataset

```

## MCP server setup

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