# Google Ads Transparency Scraper — Ad Copy, Regions & Dates (`highbrow_fame/google-ads-transparency`) Actor

Scrape the Google Ads Transparency Center: every ad an advertiser runs, with the ad copy, image or YouTube video, first and last shown dates and regions. Search by name, website or advertiser ID.

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

## Pricing

$1.50 / 1,000 ad delivereds

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 — Ad Copy, Regions & Dates

**See every ad a competitor runs on Google, with the ad's own words wherever Google keeps them.** Paste advertiser names, websites or advertiser IDs and get one clean row per ad from the [Google Ads Transparency Center](https://adstransparency.google.com/): the **headline, description, display URL and call to action**, the image or YouTube video, the **first and last day it was shown**, every country it ran in, and, for ads shown in the EU, **how many times it was shown** per country and per platform.

No Google account, no login, no cookies. Many advertisers in one run.

👉 **[Run the prefilled example](https://apify.com/highbrow_fame/google-ads-transparency)**: Nike's 20 newest US ads, copy included, in about a minute.

### Why this Google Ads Transparency scraper

- **The ad copy is on the row.** `headline`, `description`, `displayUrl` and `callToAction` are plain columns, read from the ad's own preview wherever Google keeps the ad as text. Shopping ads give the product title, merchant and product image; video ads the YouTube link, thumbnail and length. No extra switch and no extra fee for the text.
- **Names that find the right account.** Type `Nike` and you get **Nike, Inc.**, the account with 9,000+ ads, not the first lookalike in Google's search box. Websites (`nike.com`), advertiser IDs (`AR…`) and links copied from the Transparency Center work too, mixed in one list.
- **Filters that matter.** Country (or anywhere), format (text, image, video) and a date range.
- **Regions and reach.** Every country an ad ran in, with its first and last shown dates. For ads shown in the EU, Google's "times shown" ranges per country and per platform (Google Search, YouTube, Shopping, Maps, Play).
- **You pay only for ads you get.** An advertiser that does not exist, a website without ads or a request Google refuses is a free status row that says why. An ad we could not read completely is delivered free and marked `PARTIAL`.

### What you can do with it

- **Competitor research:** read the headlines and offers a competitor has kept running for months; `daysShown` tells you which ones they trust.
- **Agency pitches and audits:** pull a prospect's live ads by country before the meeting.
- **Creative swipe files:** collect image, Shopping and YouTube ads with their copy for a market or a season.
- **Market monitoring:** schedule a run per week and see which brands start or stop advertising in a country.
- **Brand protection:** list every account whose ads point at your website (`yourbrand.com` as input).

### Input

| Field | What it does |
| --- | --- |
| `advertisers` | One per line: a name (`Nike`), a website (`nike.com`), an advertiser ID (`AR16735076323512287233`) or a Transparency Center link (an advertiser, a single ad, or a website search). |
| `maxAdsPerAdvertiser` | Ads to deliver per line, newest first. Default 100. |
| `region` | A country, or `anywhere`. |
| `format` | `all`, `text`, `image` or `video`. |
| `dateFrom` / `dateTo` | Only ads shown in this period (YYYY-MM-DD). |
| `maxAdvertisersPerName` | A name can match several accounts (Samsung has one per country): take this many, most ads first. Default 1. |
| `includeAdText` | Read each ad's preview for its copy and media. On by default; off gives a faster list with dates and regions. |

```json
{
    "advertisers": ["Nike", "booking.com", "AR02934798844673654785"],
    "region": "DE",
    "format": "text",
    "dateFrom": "2026-09-01",
    "dateTo": "2026-10-25",
    "maxAdsPerAdvertiser": 200
}
```

A link carries its own filters: `https://adstransparency.google.com/advertiser/AR16735076323512287233?region=GB&format=VIDEO` reads Nike's video ads shown in the UK, whatever the run's region and format say.

### Output

One record per ad:

| Field | Example |
| --- | --- |
| `advertiserName`, `advertiserId` | `Nike, Inc.`, `AR16735076323512287233` |
| `advertiserCountry`, `advertiserLegalName` | `US`, `Nike, Inc.` |
| `creativeId`, `format` | `CR…`, `TEXT` / `IMAGE` / `VIDEO` |
| `headline`, `longHeadline`, `description` | the ad's own words |
| `displayUrl`, `callToAction`, `businessName` | `www.nike.com/`, `Learn more`, `Nike House of Innovation NYC` |
| `landingDomain` | the website the ad points to |
| `imageUrl`, `videoUrl`, `videoDuration` | product or ad image, YouTube link, `2:04` |
| `previewImageUrl` | Google's picture of the ad (many text ads are kept only this way) |
| `dynamicSearchAd` | `true` when Google writes the headline from the landing page at serving time |
| `firstShown`, `lastShown`, `daysShown` | `2026-04-28`, `2026-10-26`, `135` |
| `regions` | `["DE", "AT", "GB"]` |
| `regionStats` | per country: first and last shown, times shown, per platform |
| `impressionsMin`, `impressionsMax`, `platforms` | Google's EU "times shown" range in total, and where the ad ran |
| `adUrl` | the ad's page on the Transparency Center |
| `input`, `inputType`, `matchedAdvertiser`, `region`, `status` | what the row answers |

A text ad from a run (Samsung France, region FR; `regionStats` shortened):

```json
{
    "status": "OK",
    "advertiserName": "Samsung Electronics France SASU",
    "advertiserId": "AR12824386967030464513",
    "advertiserCountry": "FR",
    "creativeId": "CR15969925065051471873",
    "format": "TEXT",
    "headline": "Samsung The Freestyle 2nd Gen - Jusqu'à 300€ de remise*",
    "description": "Samsung Week : Jusqu'à 300€ de remise immédiate pour l'achat d'un Projecteur. The Freestyle corrige automatiquement les images de travers pour obtenir un écran droit. …",
    "displayUrl": "www.samsung.com/",
    "landingDomain": "samsung.com",
    "firstShown": "2025-10-22",
    "lastShown": "2026-10-26",
    "daysShown": 367,
    "regions": ["FR"],
    "regionStats": [
        {
            "region": "FR", "regionName": "France", "firstShown": "2025-10-22", "lastShown": "2026-10-26",
            "impressionsMin": 125000, "impressionsMax": 150000,
            "platforms": [
                { "platform": "Google Search", "impressionsMin": 125000, "impressionsMax": 150000 },
                { "platform": "Google Shopping", "impressionsMin": 0, "impressionsMax": 1000 }
            ]
        }
    ],
    "impressionsMin": 125000,
    "impressionsMax": 150000,
    "platforms": ["Google Search", "Google Shopping", "Google Maps"],
    "variationCount": 3,
    "adUrl": "https://adstransparency.google.com/advertiser/AR12824386967030464513/creative/CR15969925065051471873?region=FR"
}
```

An input that gives no ads is one free row with its reason, for example `{"input": "Zzqx Brand", "status": "NOT_FOUND", "error": "No advertiser named \"Zzqx Brand\" in the Ads Transparency Center. …"}`. The statuses: `OK`, `PARTIAL`, `NOT_FOUND`, `NO_ADS`, `INVALID_INPUT`, `FAILED`.

### Good to know

- **Reach figures exist only for ads shown in the EU.** Google publishes "times shown", platform and per-country ranges under the EU Digital Services Act. For ads shown only outside the EU those fields are `null`, and Google fills them in for new EU ads only after a while; the regions and dates are always there.
- **Times shown are Google's ranges**, such as 100,000-125,000. The top bucket has no upper end (`impressionsMax: null`).
- **Many text ads are kept by Google only as a picture**, especially older ones and those of some large advertisers. For them you get `previewImageUrl`, and the text fields stay empty.
- **Dynamic Search Ads** have no fixed headline: Google writes it from the landing page each time. They come with `dynamicSearchAd: true`, the description and an empty `headline`.
- **Keyword insertion and ad customizers** stay as the advertiser wrote them, for example `Discover {KeyWord:Nike Shoes} Online`.
- **Dates:** Google's date filter covers periods that reach into the last 12 months. For an older period the ads are matched by their first and last shown dates instead.
- **The final click URL is not public.** Google shows the display URL and the website the ad points to; that is what you get.

### Pricing

Pay per ad delivered, with no start fee: the price per ad is on the **Pricing** tab. Not-found advertisers, websites without ads, failed requests and `PARTIAL` ads are free. Set a maximum charge on the run if you want a hard cap.

### Run it from code or an AI agent

Every run is a normal Apify run: start it from the [Apify API](https://docs.apify.com/api/v2), schedule it, or connect it to Make, Zapier, n8n or Google Sheets. AI agents can call it through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp): "find the YouTube ads Spotify ran in Germany this month and summarise their headlines".

👉 **[Start your first run](https://apify.com/highbrow_fame/google-ads-transparency)**: three competitors, one country, their ad copy in a spreadsheet in minutes.

### More tools from us

- [Google Maps Email Extractor & Lead Scraper](https://apify.com/highbrow_fame/google-maps-email-extractor): businesses with e-mails and phone numbers.
- [AI Rank Tracker: AI Visibility & Brand Monitor](https://apify.com/highbrow_fame/ai-search-visibility-tracker): how AI assistants talk about your brand.
- [Google Trends API & Scraper](https://apify.com/highbrow_fame/google-trends-reliable): interest over time and by region.
- [Google Play API & Scraper](https://apify.com/highbrow_fame/google-play-apps-reviews): apps, search and reviews.

Questions or a field you miss? Open an issue on the **Issues** tab; we read every one.

# Actor input Schema

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

One per line: an advertiser name (Nike), a website (nike.com), an advertiser ID (AR16735076323512287233) or a link copied from adstransparency.google.com (an advertiser, one ad, or a website search). Mix them freely.

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

How many ads to deliver for each line above (for a name, for each matched advertiser account). Newest ads first.

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

Only ads shown in this country. "Anywhere" covers every country.

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

Text (search) ads, image ads (display and Shopping) or video ads.

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

Optional, YYYY-MM-DD. Only ads shown on or after this date. Without "Shown to", up to today.

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

Optional, YYYY-MM-DD. Only ads shown on or before this date. Without "Shown from", the year before it.

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

A name can match several advertiser accounts (Samsung has one per country). Take this many, the ones with the most ads first.

## `includeAdText` (type: `boolean`):

Read each ad's preview for its headline, description, display URL, call to action, image and YouTube video. Turn off for a faster list of ads with dates and regions only.

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

How many advertisers to work on at the same time.

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

Apify Proxy settings. The default works for most runs.

## Actor input object example

```json
{
  "advertisers": [
    "Nike"
  ],
  "maxAdsPerAdvertiser": 20,
  "region": "US",
  "format": "all",
  "maxAdvertisersPerName": 1,
  "includeAdText": true,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Every result as a JSON record, with a status for each input.

## `resultsCsv` (type: `string`):

The same records as CSV, for a spreadsheet.

# 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 = {
    "advertisers": [
        "Nike"
    ],
    "maxAdsPerAdvertiser": 20,
    "region": "US",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("highbrow_fame/google-ads-transparency").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 = {
    "advertisers": ["Nike"],
    "maxAdsPerAdvertiser": 20,
    "region": "US",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("highbrow_fame/google-ads-transparency").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 '{
  "advertisers": [
    "Nike"
  ],
  "maxAdsPerAdvertiser": 20,
  "region": "US",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call highbrow_fame/google-ads-transparency --silent --output-dataset

```

## MCP server setup

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

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/jk97OL7ZdU7Qa2yKf/builds/HVMVaHppa0bek9I5X/openapi.json
