# Google Ads Transparency Scraper (`agnes.developer.queen/google-ads-transparency-scraper`) Actor

Google Ads Transparency Scraper pulls the ads any company runs on Google from the Ads Transparency Center, by domain or advertiser name. It returns ad text, image or video, first and last shown dates, days running and a link to each ad. Monitor mode returns only ads new since your last run.

- **URL**: https://apify.com/agnes.developer.queen/google-ads-transparency-scraper.md
- **Developed by:** [Agnes Maina](https://apify.com/agnes.developer.queen) (community)
- **Categories:** Marketing, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 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: competitor ads with copy, pictures, videos and dates

Google Ads Transparency Scraper is an Apify Actor that pulls the ads a company runs on Google from the Ads Transparency Center, by website domain or advertiser name, and returns the ad itself, its first and last shown dates, and the countries where it ran.

### Pricing

| Event | Price | You pay when |
|---|---|---|
| Actor start | $0.00005 | once per run |
| Ad | $0.003 | an ad is delivered with its IDs, its shown dates and its content (text, picture or video) |

**That is $3 per 1,000 ads. Ads with no text, picture or video are delivered free, with their preview link.**

### The ad itself, not a preview link

Most Transparency Center scrapers return a preview link for text and video ads, so you open each one by hand to see it. This Actor returns the ad.

- Text ads give Google's rendered picture of every variation. When Google publishes the copy as text, you also get the headline, the description, the display URL and the sitelinks as text.
- Shopping ads give the product title, the product photo and the merchant.
- Video ads give the YouTube link when Google embeds one.
- Image ads give the image.

Every ad also comes with the countries where it ran, the first and last shown date in each country, and the times-shown range Google publishes for some countries.

```json
{
    "advertiserName": "Nike Retail BV",
    "format": "text",
    "adType": "search",
    "headline": "Nike Vomero",
    "description": "Discover Nike Shoes Online At Nike.com. Shop The Official Nike Site.",
    "displayUrl": "nike.com",
    "sitelinks": [],
    "firstShown": "2025-10-22",
    "lastShown": "2026-09-23",
    "daysShown": 337,
    "transparencyUrl": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR06103840103250001921",
    "countries": [
        {
            "country": "CZ",
            "firstShown": "2025-10-22",
            "lastShown": "2026-09-23",
            "timesShownLow": 2000,
            "timesShownHigh": 3000
        },
        {
            "country": "DK",
            "firstShown": "2025-10-23",
            "lastShown": "2026-09-23",
            "timesShownLow": null,
            "timesShownHigh": 1000
        },
        {
            "country": "BE",
            "firstShown": "2025-10-22",
            "lastShown": "2026-09-22",
            "timesShownLow": null,
            "timesShownHigh": 1000
        }
    ]
}
```

### How it works

```
domains or advertiser names
            |
            v
Ads Transparency Center search, 40 ads per page
            |
            v
for each ad, read the per-country record and the pictures of every variation,
and decode the text where Google publishes it
            |
            +--> IDs, dates and content  -->  Ad (charged)
            |
            +--> no content              -->  delivered free with the preview link
```

### What data does it extract

| Field | What it is |
|---|---|
| `advertiserName`, `advertiserId` | The advertiser as Google verified it |
| `domain` | The advertiser's website |
| `creativeId` | The ad's ID in the Transparency Center |
| `format`, `adType` | text, image or video, and search when the text was decoded, shopping, image, video or text |
| `headline`, `description`, `displayUrl`, `sitelinks` | The ad copy, when Google publishes it as text |
| `imageUrl` | A picture of the ad when Google publishes one. The creative for image ads, Google's rendering for text ads, the product photo for shopping ads |
| `variations` | Google's rendered picture of each variation of the ad |
| `videoUrl` | YouTube link of a video ad when Google embeds one |
| `merchant` | Merchant name on shopping ads |
| `firstShown`, `lastShown`, `daysShown` | When the ad ran |
| `countries` | Each country with its first and last shown date and Google's times-shown range where published |
| `transparencyUrl`, `previewUrl` | Links to the ad in the Transparency Center |
| `isNew` | In monitor mode, true when the ad is new since your last run |
| `charged`, `reason` | Whether the row was charged, and why |

### What is NOT returned

- Ad spend or budgets. Google does not publish them.
- The copy of text ads as text when Google publishes it only as pictures. You get the pictures of every variation.
- Audience targeting, keywords or bids.
- Clicks, conversions or landing page performance.
- Times-shown ranges for countries where Google does not publish them.
- Ads Google has removed from the Transparency Center.
- Content of some rich display ads that only render inside Google's player. They are delivered free with the preview link.

### Quick start

1. Open the Actor and enter a competitor's website, for example `nike.com`.
2. Optionally choose a country and an ad format.
3. Run it and open the Ads table, or download JSON, CSV or Excel.

```json
{ "domains": ["nike.com"], "region": "anywhere", "format": "all", "maxAdsPerAdvertiser": 20 }
```

### Monitor mode

Set `onlyNewSinceLastRun` to true and schedule the run daily or weekly. The first run delivers current ads up to your limit and remembers every ad it saw. Each later run delivers only ads that appeared since, marked `isNew`, and you pay only for those.

### Input

```json
{
    "domains": ["nike.com", "adidas.com"],
    "advertisers": ["HubSpot"],
    "region": "US",
    "format": "text",
    "maxAdsPerAdvertiser": 100,
    "onlyNewSinceLastRun": false
}
```

| Field | Type | Default | Description |
|---|---|---|---|
| `domains` | array | | Advertiser websites, for example `nike.com` |
| `advertisers` | array | | Advertiser names exactly as Google verified them (Inc or LLC can be left off), or advertiser IDs that start with AR. When several advertisers share a name, the largest one and same-name accounts in its country are used, and the log lists the others with their IDs |
| `region` | string | `anywhere` | Two-letter country code. Only ads shown in that country are delivered |
| `format` | string | `all` | `all`, `text`, `image` or `video` |
| `maxAdsPerAdvertiser` | integer | 50 | Stop after this many ads per domain or advertiser, up to 1,000 |
| `onlyNewSinceLastRun` | boolean | false | Monitor mode, deliver only ads new since the last run of the same search |
| `proxyConfiguration` | object | Apify residential | Proxy for the small search calls. Ad previews always use datacenter proxy |

### Output

One full record from a real run.

```json
{
    "advertiserName": "Nike Retail BV",
    "advertiserId": "AR18378488041124659201",
    "domain": "nike.com",
    "creativeId": "CR17279215814825738241",
    "format": "text",
    "adType": "search",
    "headline": "Nike Basketball Shoes",
    "description": "Discover Nike Shoes Online At Nike.com. Shop The Official Nike Site.",
    "displayUrl": "nike.com",
    "sitelinks": [],
    "imageUrl": "https://tpc.googlesyndication.com/archive/simgad/10990147604733979610",
    "variations": [
        "https://tpc.googlesyndication.com/archive/simgad/10990147604733979610"
    ],
    "videoUrl": null,
    "merchant": null,
    "firstShown": "2025-10-24",
    "lastShown": "2026-09-23",
    "daysShown": 334,
    "countries": [
        {
            "country": "RO",
            "firstShown": "2025-11-04",
            "lastShown": "2026-09-18",
            "timesShownLow": null,
            "timesShownHigh": 1000
        },
        {
            "country": "CZ",
            "firstShown": "2025-11-03",
            "lastShown": "2026-09-22",
            "timesShownLow": null,
            "timesShownHigh": 1000
        },
        {
            "country": "DE",
            "firstShown": "2025-10-24",
            "lastShown": "2026-09-23",
            "timesShownLow": 6000,
            "timesShownHigh": 7000
        },
        {
            "country": "PL",
            "firstShown": "2025-10-24",
            "lastShown": "2026-09-22",
            "timesShownLow": null,
            "timesShownHigh": 1000
        },
        {
            "country": "NL",
            "firstShown": "2025-10-24",
            "lastShown": "2026-09-23",
            "timesShownLow": 50000,
            "timesShownHigh": 60000
        },
        {
            "country": "ES",
            "firstShown": "2025-10-26",
            "lastShown": "2026-09-20",
            "timesShownLow": null,
            "timesShownHigh": 1000
        },
        {
            "country": "IT",
            "firstShown": "2025-11-04",
            "lastShown": "2026-09-22",
            "timesShownLow": null,
            "timesShownHigh": 1000
        },
        {
            "country": "BE",
            "firstShown": "2025-10-25",
            "lastShown": "2026-09-23",
            "timesShownLow": 7000,
            "timesShownHigh": 8000
        },
        {
            "country": "FR",
            "firstShown": "2025-11-05",
            "lastShown": "2026-09-08",
            "timesShownLow": null,
            "timesShownHigh": 1000
        },
        {
            "country": "PT",
            "firstShown": "2025-11-11",
            "lastShown": "2026-09-10",
            "timesShownLow": null,
            "timesShownHigh": 1000
        },
        {
            "country": "HU",
            "firstShown": "2025-11-06",
            "lastShown": "2026-08-27",
            "timesShownLow": null,
            "timesShownHigh": 1000
        },
        {
            "country": "GR",
            "firstShown": "2025-11-05",
            "lastShown": "2026-09-02",
            "timesShownLow": null,
            "timesShownHigh": 1000
        },
        {
            "country": "SK",
            "firstShown": "2025-11-09",
            "lastShown": "2026-09-23",
            "timesShownLow": null,
            "timesShownHigh": 1000
        }
    ],
    "transparencyUrl": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR17279215814825738241",
    "previewUrl": "https://displayads-formats.googleusercontent.com/ads/preview/content.js?client=ads-integrity-transparency&obfuscatedCustomerId=9151524834&creativeId=775607536946&uiFeatures=12&adGroupId=189588175887&versionId=13&assets=%3DH4sIAAAAAAAAAONS4OLkOHD7S-d5TgFmLk6Oe1cu_TrAIcDIxcHxc9GEHhUBRil2jmedq66eYZJi57g_v2fKIZDIg7tvzr0Dicy6BmUsvg9iAACwPMX6TwAAAA&allowedVariations=39&sig=ACiVB_xZXuuhte4blmgvxLxcf2grWspKbw&htmlParentId=fletch-render-15835437447088133956&responseCallback=fletchCallback15835437447088133956",
    "isNew": null,
    "charged": true,
    "reason": "ad with content and dates",
    "scrapedAt": "2026-09-23T22:44:30.181Z"
}
```

### Use from any MCP agent

```
https://mcp.apify.com/?tools=agnes.developer.queen/google-ads-transparency-scraper
```

Ask the agent for the text ads a competitor ran in a country this month. It should read `headline` and `description` where present, `variations`, `countries` and `lastShown`.

### Integrations

Call it once per row from Clay, n8n, Make or your own code. This returns the dataset in the same request.

```
POST https://api.apify.com/v2/acts/agnes.developer.queen~google-ads-transparency-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN
Content-Type: application/json

{ "domains": ["nike.com"], "maxAdsPerAdvertiser": 20 }
```

It also works with `apify-client`, schedules and webhooks.

### Use cases

- **Performance marketing agencies.** Pull every search ad a prospect's three rivals ran last month and open the pitch with their copy.
- **Competitive intelligence teams.** Schedule monitor mode weekly on ten competitors and get only the new ads.
- **Copywriters.** Build a swipe file of a category's ads, with the picture of every variation and the copy where Google publishes it as text, sorted by how long each ad has run.
- **Sales teams selling ad services.** Find companies that advertise on Google in a country and see what they say.

### FAQ

#### Does it return ad spend?

No. Google does not publish spend in the Ads Transparency Center. You get the ads, their dates and countries, and Google's times-shown range where Google publishes one.

#### Why was an ad delivered free?

Google published no text, picture or video for it, usually a rich display ad that only renders inside Google's player. The `reason` field says so, and the `previewUrl` still opens it.

#### Why do some text ads have pictures but no headline?

Google publishes most text ads in the Transparency Center only as rendered pictures. The Actor returns the picture of every variation, and adds the text whenever Google publishes it as text.

#### Why did an advertiser name return nothing?

Names must match the name Google verified, apart from Inc or LLC. The run log lists the names Google suggested. A website domain or an advertiser ID always works.

#### Do I need a Google account or cookies?

No. The Actor reads the public Ads Transparency Center.

#### Can I filter by country or format?

Yes. Set `region` to a two-letter country code and `format` to text, image or video. Ads that did not run in that country are not delivered.

#### How often should I run monitor mode?

Weekly is enough for most advertisers. Daily suits advertisers that test new copy often. Each run charges only for new ads.

# Actor input Schema

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

Advertiser websites, for example nike.com. Returns the ads Google shows for that domain in the Ads Transparency Center.

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

Optional. Advertiser names exactly as Google verified them, for example HubSpot (Inc or LLC can be left off), or Transparency Center advertiser IDs that start with AR. When several advertisers share a name, the largest one and same-name accounts in its country are used, and the run log lists the others with their IDs.

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

Two-letter country code such as US, GB or DE. Only ads shown in that country are delivered. Use anywhere for all countries.

## `format` (type: `string`):

Deliver only text, image or video ads, or all formats.

## `maxAdsPerAdvertiser` (type: `integer`):

Stop after this many ads for each domain or advertiser. Only ads with IDs, dates and content (text, picture or video) are charged.

## `onlyNewSinceLastRun` (type: `boolean`):

Monitor mode. The first run delivers current ads up to your limit and remembers every ad it saw. Later runs of the same search deliver only ads that appeared since. Schedule it daily or weekly to watch competitors.

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

Proxy for the Transparency Center search calls. Residential keeps Google's rate limit away and these calls are small. Ad previews always use datacenter proxy.

## Actor input object example

```json
{
  "domains": [
    "nike.com"
  ],
  "region": "anywhere",
  "format": "all",
  "maxAdsPerAdvertiser": 20,
  "onlyNewSinceLastRun": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

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

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

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

```

## MCP server setup

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