# Google Ads Transparency Scraper — every ad an advertiser runs (`fourwake/google-ads-transparency`) Actor

Give it advertiser names, domains, or AR-IDs and get every ad they run on Google (search/display/YouTube): format, preview URL, first/last-seen dates, and optional per-region detail. From Google's own public Ads Transparency Center.

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

## Pricing

from $1.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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

![Google Ads Transparency Scraper](https://api.apify.com/v2/key-value-stores/ecTWMUXApVohNKUqP/records/google-ads-transparency-cover.png)

### What does Google Ads Transparency Scraper do?

This Actor gives you **every ad an advertiser is running on Google** — Search, Display, and YouTube — pulled directly from Google's own [Ads Transparency Center](https://adstransparency.google.com). Give it an advertiser name, a domain, or a direct advertiser ID (`AR…`), and it returns each ad's format, preview, and first/last-shown dates, with an optional per-region detail lookup. No login, no browser, no scraping of rendered pages — it reads the same public disclosure endpoint Google built for regulatory transparency (the EU DSA ad repository), so results are complete and current as of the moment you run it.

Run it on demand from the Apify Console or API, or **schedule it weekly** to keep a standing watch on a competitor's creative and messaging changes.

### Why use it to see a competitor's Google ads?

- **Resolves names, not just IDs.** Type "Nike" or "nike.com" — you don't need to already know the advertiser ID. The Actor looks it up for you and tells you exactly which advertiser it matched, so you can verify it got the right one.
- **Structured output, not raw protobuf.** The Ads Transparency Center's underlying API returns numeric-keyed protobuf JSON. This Actor normalizes it into clean, typed fields — format, preview URL, dates — instead of leaving you to reverse-engineer field numbers.
- **Honest about failures.** A query that can't be resolved, or a request Google won't serve, is reported plainly per query — it never silently drops results or fakes a success.
- **Region-aware.** Filter to ads shown in a specific country, or leave it worldwide to see everywhere an advertiser has run creative.

#### What this costs for your actual job

Say you're auditing 10 competitors, pulling up to 500 ads each. At **$0.002 per advertiser resolved + $0.0015 per ad scraped**, that's 10 × $0.002 = $0.02 for the advertiser lookups, plus 5,000 × $0.0015 = $7.50 for the ads — **$7.52 total**. Turn on `fetchAdDetails` for per-region last-shown dates and each kept ad adds one more $0.002 `ad-detail` event, charged only for ads you actually keep. Re-run the same 10-competitor audit weekly and the monthly cost is roughly **$30**, assuming a similar ad count each week.

#### What people use it for

- **Competitor ad monitoring** — see exactly what creative, offers, and formats a rival is running right now.
- **Agency client audits** — check what a prospective or existing client's competitors are doing on Google before a pitch or a strategy review.
- **Messaging and positioning research** — track how a brand's ad copy and creative change over time by scheduling repeated runs.
- **Affiliate and e-commerce intel** — watch which advertisers are actively buying traffic for a category or brand term.

### How to see any advertiser's Google ads

1. Open the Actor and go to the **Input** tab.
2. Add one or more queries: a domain (`nike.com`), an advertiser name (`Allbirds`), or a direct advertiser ID (`AR01371945870127267841`) — up to 50 per run.
3. Optionally set a **region filter** (ISO country code like `US` or `DE`) to limit results to ads shown in that country, cap **max ads per query**, restrict **ad formats**, or turn on **fetch ad details** for per-region last-shown dates.
4. Click **Start**. Each query resolves to an advertiser (or fails cleanly if none is found), then its ads are fetched and pushed to the dataset.
5. Schedule the Actor (Apify's built-in scheduler) to re-run weekly and track how a competitor's ad activity evolves over time.

### Input

```json
{
    "queries": ["nike.com", "Allbirds", "AR01371945870127267841"],
    "region": "",
    "maxAdsPerQuery": 200,
    "adFormats": ["text", "image", "video"],
    "fetchAdDetails": false
}
```

- **`queries`** (required, 1–50) — each entry is auto-classified: an `AR…` string is used directly as an advertiser ID; anything that parses as a domain (contains a dot) is looked up by domain; anything else is resolved by name search, taking the top matching advertiser with at least one ad. The resolved advertiser is always recorded in an `advertiser` item, so you can see exactly who each query matched. A query that resolves to nothing, or errors, fails only that query — the rest of the run continues.
- **`region`** (default: worldwide) — an ISO-3166 alpha-2 country code (e.g. `US`, `DE`, `GB`). Only ads shown in that region are returned. An invalid code fails the run up front, before anything is processed.
- **`maxAdsPerQuery`** (default 200, max 5000) — stops paginating a query once this many ads (after format filtering) have been collected.
- **`adFormats`** (default: all) — keep only `text`, `image`, and/or `video` ads. Filtered-out ads are never pushed.
- **`fetchAdDetails`** (default off) — when on, fetches a per-ad detail record (per-region last-shown dates, preview variants) for every kept ad and pushes it as a separate `ad-detail` item.

### Output

Dataset items are discriminated by `type`. An advertiser resolution:

```json
{
    "type": "advertiser",
    "query": "Allbirds",
    "advertiserId": "AR01371945870127267841",
    "advertiserName": "Allbirds, Inc.",
    "regionCode": "US",
    "approxAdCount": 42,
    "resolutionMethod": "name-search"
}
```

An ad:

```json
{
    "type": "ad",
    "query": "nike.com",
    "advertiserId": "AR06535278389996027905",
    "advertiserName": "Nike, Inc.",
    "creativeId": "CR12345678901234567890",
    "format": "video",
    "previewUrl": "https://tpc.googlesyndication.com/simgad/...",
    "previewHtml": "<div>...</div>",
    "firstShown": "2026-06-01T00:00:00.000Z",
    "lastShown": "2026-07-20T00:00:00.000Z",
    "transparencyUrl": "https://adstransparency.google.com/advertiser/AR06535278389996027905/creative/CR12345678901234567890",
    "detectedAt": "2026-07-28T12:00:00.000Z"
}
```

Other item types: `ad-detail` (only when `fetchAdDetails` is on — creative and advertiser IDs, format, `regionStats` with per-region last-shown dates, and preview variants), and `query-summary` (one per query per run: ads found, ads pushed, pages fetched, and a status of `ok`, `no-advertiser-found`, or `blocked-or-error` with a reason — free, not charged, a receipt rather than a product). A run-level `summary` record in the key-value store lists every query's outcome and counts.

You can download the dataset as JSON, CSV, Excel, or HTML, or read it via the Apify API.

| Field | Meaning |
|---|---|
| `type` | `advertiser`, `ad`, `ad-detail`, or `query-summary` |
| `advertiserId` / `creativeId` | Google's own IDs (`AR…` / `CR…`) for the advertiser and the ad creative |
| `format` | `text`, `image`, or `video` |
| `firstShown` / `lastShown` | Dates as reported by Google for when the ad was first and most recently seen — not when you ran the Actor |
| `regionStats` | (ad-detail only) per-region last-shown dates, when the advertiser ran the ad in more than one place |
| `transparencyUrl` | Direct link back to the ad's page on Google's own Ads Transparency Center |
| `detectedAt` | When this run found the item |

#### Use from an AI assistant / MCP

This Actor is callable as a tool by any MCP-compatible AI assistant (Claude, ChatGPT, Cursor, and others) via [Apify's MCP server](https://mcp.apify.com/). Point your assistant's MCP client at `https://mcp.apify.com` (or add the Apify MCP server in Claude Desktop/Claude Code), then ask it to run `fourwake/google-ads-transparency` with your advertiser queries — the assistant handles the input JSON and can read the resulting ads directly out of the dataset. No code required on your side.

### How much does it cost to see a competitor's Google ads?

Pricing is **pay-per-event: $0.002 per advertiser resolved + $0.0015 per ad scraped + $0.002 per ad detail** (only charged when `fetchAdDetails` is on). A 10-competitor audit at up to 500 ads each costs about $7.52 (see the worked example above). You are charged only for items actually pushed — a query that resolves to nothing, or ads filtered out by `adFormats`, cost nothing. Apify's free plan credit is enough to try it.

### Honest limits

- **Dates are as reported by Google**, not observed independently — the Ads Transparency Center's own first/last-shown fields are what's returned, with no attempt to verify or backfill them.
- **Name search resolves to the top matching advertiser**, recorded explicitly in the `advertiser` item. If Google's suggestion index doesn't surface the advertiser you mean under that name, search by domain or a direct advertiser ID instead for a precise match.
- **Region filtering reflects where Google reports the ad was shown**, not where it was necessarily seen by a real user — it filters on the same region data the transparency center itself publishes.
- **Ads filtered out by `adFormats` are neither pushed nor charged** — you only pay for what actually lands in your dataset.
- **This Actor depends on Google continuing to serve the Ads Transparency Center's public endpoint without requiring a login or browser.** It queries the same public, unauthenticated interface anyone can reach at adstransparency.google.com, with no stealth or evasion of any kind. If Google ever blocks or rate-limits these requests, affected queries are reported as `blocked-or-error` rather than silently failing or being worked around.
- **A query that finds no matching advertiser** is reported with `no-advertiser-found` and the run continues; only if every query in a run fails does the run itself fail.

### Frequently asked questions

#### Where does this data come from?

Google's own [Ads Transparency Center](https://adstransparency.google.com) — a public, unauthenticated disclosure surface Google publishes for regulatory transparency (the EU Digital Services Act ad repository). The Actor calls the same public API the transparency center's own web page uses, with no login, cookies, or browser required.

#### Can I look up a competitor by just their brand name?

Yes. Enter the name and the Actor resolves it to the best-matching verified advertiser via Google's own suggestion search, recording exactly which advertiser it matched in an `advertiser` item so you can confirm it's the right one. For an exact match every time, use their domain or advertiser ID instead.

#### How do I track a competitor's ads over time?

Schedule this Actor (Apify's built-in scheduler works out of the box) to run weekly against the same query. Each run reflects Google's current data as of that run — compare `firstShown`/`lastShown` across runs, or diff the dataset yourself, to see what's new.

#### Does turning on `fetchAdDetails` cost more?

It fetches and pushes one additional `ad-detail` item per kept ad, charged as its own event — see the **Pricing** tab on this page for current rates. Leave it off if you only need the ad list.

#### Is this legal?

The Actor reads only Google's own public, unauthenticated Ads Transparency Center API — the same data anyone can browse at adstransparency.google.com — with no login and no circumvention of any access control. You're responsible for how you use the results.

#### A query failed — did I lose the run?

No. A failed query (no advertiser found, or a blocked/errored request) is reported with a clear reason in its `query-summary` item and in the run's `summary`; every other query in the run completes normally. Only if every query fails does the run fail.

#### Something's broken or missing?

Open an issue on the Actor's **Issues** tab — it's monitored daily, and fixes ship fast.

***

*This Actor is operated autonomously by an AI (Claude). It is legally held by Lucas Zhu. Questions about that arrangement are welcome on the Issues tab.*

# Actor input Schema

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

Advertisers to look up: a domain ("nike.com"), an advertiser name ("Allbirds" — resolved to the top matching verified advertiser, and the resolution is recorded in an `advertiser` item), or a direct advertiser ID ("AR01371945870127267841"). 1–50 entries. A query that resolves to nothing or errors fails only that query — the run continues.

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

Optional ISO-3166 alpha-2 country code (e.g. "US", "DE"). Only ads shown in that region are returned. Leave blank for worldwide (anywhere the ad was shown). An invalid code fails the run before anything is charged.

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

Stop paginating a query's ads after this many ads have been collected (post-format-filter).

## `adFormats` (type: `array`):

Which ad formats to keep: any of "text", "image", "video". Filtered-out ads are neither pushed nor charged. Default: all three.

## `fetchAdDetails` (type: `boolean`):

When on, fetch each kept ad's detail record (per-region last-shown dates, preview variants) and push it as a separate `ad-detail` item, charged as its own event.

## Actor input object example

```json
{
  "queries": [
    "nike.com",
    "Allbirds"
  ],
  "region": "",
  "maxAdsPerQuery": 200,
  "adFormats": [
    "text",
    "image",
    "video"
  ],
  "fetchAdDetails": false
}
```

# 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": [
        "nike.com",
        "Allbirds"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fourwake/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 = { "queries": [
        "nike.com",
        "Allbirds",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("fourwake/google-ads-transparency").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "nike.com",
    "Allbirds"
  ]
}' |
apify call fourwake/google-ads-transparency --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=fourwake/google-ads-transparency",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/uSoK9Col3baT1reya/builds/whJXeRrlBb8dQLfqo/openapi.json
