# Google Ads Transparency Scraper + New Ads Monitor (`ninoventures/google-ads-transparency-monitor`) Actor

All Google ads an advertiser or domain runs, from the Google Ads Transparency Center: format, first/last shown, image or YouTube link, and optionally headline, body, landing page and per-country reach. Monitoring mode outputs only new ads.

- **URL**: https://apify.com/ninoventures/google-ads-transparency-monitor.md
- **Developed by:** [Nino Ventures](https://apify.com/ninoventures) (community)
- **Categories:** Marketing, SEO tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

Pulls every ad an advertiser runs on Google (Search, YouTube, Display) from the public [Google Ads Transparency Center](https://adstransparency.google.com), as a table you can export. Turn on monitoring and schedule it daily, and each run gives you only the ads that went live since the last run.

No login, no Google account, no API key.

### What you give it

A list of any of these, mixed:

- a domain: `gymshark.com`
- an advertiser name: `Notion Labs`
- an advertiser ID: `AR05501100765344694273`
- a Transparency Center URL

Plus a region (`US`, `GB`, `NL`... or `anywhere`) and how many ads per advertiser you want. Newest ads come first.

Names are matched to an advertiser whose legal name contains that exact word. If there is none, it falls back to the matching domain. For example, "Canva" has no advertiser called Canva in the suggestions, so the actor uses `canva.com`. The other candidates are listed in the `SUMMARY` record, so you can switch to the right ID if the match is wrong.

### What you get per ad

| Field | Example |
|---|---|
| advertiserName, advertiserId | Notion Labs, Inc / AR13309761427309854721 |
| creativeId | CR03221002623326879745 |
| format | TEXT, IMAGE or VIDEO |
| firstShown, lastShown, daysShown | 2026-06-24, 2026-10-31, 131 |
| imageUrl | Google's rendered image of the ad (all image ads and search text ads) |
| adUrl | link to the ad in the Transparency Center |
| isNewSinceLastRun | true/false from the second run on |

With **Add ad copy, landing page and per-country reach** on:

| Field | Example |
|---|---|
| headline, body, callToAction | "One AI workspace tailored to every team" |
| landingPage, displayUrl | https://www.notion.com/lp/ent?nid=ddvmq9t |
| youtubeVideoId, youtubeUrl | -jPiUEo_MWg |
| variations | 4 |
| regions | country, last shown date, and impression range where Google publishes it (EU countries only, e.g. NL: 10,000–15,000) |

Things to know before you rely on this:

- Google shows search text ads only as an image. Those rows get an `imageUrl` but no `headline` or `landingPage`.
- Headline and landing page come from the ad preview. Google includes them for most Demand Gen / Discovery image ads and some video ads, not all.
- Impression ranges exist only for EU countries, because that is all Google publishes.

### Numbers from our own test run (31 Oct 2026, region US)

Input: `Canva`, `gymshark.com`, `hellofresh.com`, `Notion Labs` and one advertiser ID, with up to 200 ads each and details on.

- 779 ads in 2 min 45 s. Platform cost for the run: about $0.011.
- 352 text, 238 video and 189 image ads.
- 232 of the 238 video ads came with a YouTube video ID. 94 ads (12%) had a headline and landing page. Every ad had a country list.
- Totals Google reports for the US: canva.com 10,000–20,000 ads, gymshark.com 2,000–3,000, hellofresh.com 800–900, Notion Labs, Inc 100–200.
- We ran the same input again 8 minutes later with "only new ads" on. It checked 779 ads in 10 seconds and returned 1 new Canva ad.

### Monitoring competitors

1. Put your competitors in `queries` and set the region.
2. Run once with **Only output ads not seen in earlier runs** on. The first run outputs everything and becomes the baseline.
3. Add a daily schedule in Apify. From then on, each run's dataset contains only new creatives, so it is cheap and easy to pipe into Slack, Sheets or email with an Apify integration.

Use **Monitor name** if you keep several separate watch lists.

### Pricing

Pay per result, no monthly fee:

- **$1.20 per 1,000 ads**
- **+$1.00 per 1,000 ads** for the details add-on (only when you turn it on)

Ads you filter out (older than "last shown within N days", or already seen in monitoring mode) are not charged. A daily monitor on 10 competitors that each launch a handful of ads a day costs a few cents a month.

### Speed and limits

- About 200 ads per 20–45 seconds without details. With details it is slower, because each ad is opened.
- Google rate-limits a single IP after a few hundred detail lookups. Apify Proxy (datacenter, included in the free plan) is on by default, and the actor switches IP when that happens. With the proxy off it backs off and waits.
- Large brands have tens of thousands of ads. Keep `maxAdsPerQuery` low for a first test.

### Is this allowed?

The Transparency Center is a public library that Google publishes so anyone can see who advertises what. The actor reads the same data the website shows, without logging in, and it does not collect personal data. Not affiliated with Google.

### Feedback

If a field is wrong or missing for an advertiser you care about, open an issue on the Issues tab with the advertiser ID. We fix those first.

# Actor input Schema

## `queries` (type: `array`):

One per line. Accepts an advertiser name ("Gymshark"), a website domain ("gymshark.com"), an advertiser ID (AR05501100765344694273) or a Transparency Center URL. Names are matched to the advertiser with the most ads; the other matches are listed in the SUMMARY record.

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

Two-letter country code (US, GB, NL, DE, AU...) or "anywhere". Same as the region picker on adstransparency.google.com.

## `maxAdsPerQuery` (type: `integer`):

Newest ads come first. Large brands have 10,000+ ads, so keep this low for a first test.

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

Opens each ad to read its headline, body text, call to action, landing page URL, YouTube video ID, variation count and per-country impression ranges and dates. Billed as an extra event per ad. Search text ads are shown by Google as images only, so they get an image URL but no headline.

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

Monitoring mode. The actor remembers creative IDs per query list and region. The first run outputs everything and sets the baseline; later runs output only ads that appeared since. Schedule it daily to get a competitor ad feed.

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

Keeps separate memory for separate monitors, e.g. "client-a". Leave empty if you run one monitor.

## `lastShownWithinDays` (type: `integer`):

0 = no filter. 30 gives you roughly what is running now.

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

Apify Proxy (datacenter) is on by default. Google rate-limits single IPs after a few hundred detail lookups; with the proxy the actor switches IP and keeps going. Datacenter proxy is included in Apify's free plan.

## Actor input object example

```json
{
  "queries": [
    "gymshark.com",
    "Notion Labs"
  ],
  "region": "anywhere",
  "maxAdsPerQuery": 100,
  "includeAdDetails": false,
  "onlyNewAds": false,
  "lastShownWithinDays": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "queries": [
        "gymshark.com",
        "Notion Labs"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ninoventures/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 = {
    "queries": [
        "gymshark.com",
        "Notion Labs",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("ninoventures/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 '{
  "queries": [
    "gymshark.com",
    "Notion Labs"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call ninoventures/google-ads-transparency-monitor --silent --output-dataset

```

## MCP server setup

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