# Google Ads Transparency Scraper: Ads, Dates, Regions (`actose/google-ads-transparency`) Actor

Google Ads Transparency Center ads of any domain, brand or advertiser: headline, description, image & YouTube links, first/last shown, regions. No API key, no login. MCP-ready for Claude, Cursor, ChatGPT and AI agents. Pay per result, errors and empty results are free. $1.40 per 1,000 ads.

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

## Pricing

from $1.19 / 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.
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 Scraper & API

**$1.40 per 1,000 ads ($0.0014 per ad).** Pay per result, no monthly rental, no start fee. Errors, blocked requests, duplicates and empty results are free.

Export **every Google ad** a competitor runs from the [Google Ads Transparency Center](https://adstransparency.google.com): Search (text), Display (image) and YouTube (video) ads. Search by **domain**, **advertiser name / keyword**, **advertiser ID** or a pasted **Transparency Center URL**. Filter by **region**, **format** and **date range**. Each ad is one clean JSON row with its **headline, description, display URL, image link, YouTube video link, first/last shown dates, days running**, a ready-to-use **Markdown card for LLMs** and, optionally, the **regions where it ran** and **all its variations**.

- **No API key, no login, no Google account.** Google publishes no official API for the Ads Transparency Center: this actor works as that API.
- **No browser**: it calls the same public JSON endpoints as the website, so it's fast and cheap.
- **MCP-ready**: AI agents (Claude, Cursor, ChatGPT...) can call it as a tool and get structured JSON back.
- **Built for monitoring**: `onlyNew` returns only ads that appeared since your last scheduled run.

### How much does it cost?

| Event | Price |
|---|---|
| Ad delivered (one dataset row) | **$0.0014** |

Examples:

- **100 ads** of one competitor = **$0.14**
- **1,000 ads** = **$1.40**
- **10,000 ads** = **$14.00**

What is free: runs that find no ads, ads that can't be fetched, rows with no content, duplicates (the same ad found by a domain and an advertiser search is charged once) and ads skipped by `onlyNew`. Regions and variations (**Include ad details**) cost nothing extra. Set **Maximum cost per run** in the run options: the actor stops cleanly when it is reached. The Apify datacenter proxy that comes with every plan is enough in normal conditions.

### Input example

```json
{
  "domains": ["nike.com"],
  "searchTerms": ["Decathlon"],
  "advertiserIds": ["AR14188379519798214657"],
  "startUrls": ["https://adstransparency.google.com/?region=FR&domain=adidas.com"],
  "region": "US",
  "adFormat": "all",
  "startDate": "30 days",
  "maxAdsPerQuery": 100,
  "includeDetails": false,
  "extractAdContent": true,
  "downloadImages": false,
  "onlyNew": false
}
```

You need only one of `domains`, `searchTerms`, `advertiserIds` or `startUrls`. You can mix them: the same ad is never returned (or charged) twice in a run.

| Input | What it does |
|---|---|
| `domains` | Every ad pointing to a website, from all accounts of the brand |
| `searchTerms` | Brand / company name matched to Transparency Center advertisers (`maxAdvertisersPerSearchTerm`) |
| `advertiserIds` | One verified advertiser account (`AR...`) |
| `startUrls` | Advertiser, single ad or `?domain=` URLs from the Transparency Center |
| `region` | Only ads shown in this country (`anywhere` = all) |
| `adFormat` | `all`, `text`, `image` or `video` |
| `startDate` / `endDate` | Only ads shown in this period (`YYYY-MM-DD` or `30 days`) |
| `maxAdsPerQuery` | Max ads per domain / advertiser (0 = all) |
| `includeDetails` | Adds regions with dates and all variations (same price) |
| `downloadImages` | Saves image ads to your key-value store with a permanent link |
| `onlyNew` | Only ads not delivered by your previous runs (for schedules) |

### Output example

```json
{
  "creativeId": "CR10449491775734153217",
  "advertiserId": "AR14188379519798214657",
  "advertiserName": "Nike, Inc.",
  "advertiserCountry": null,
  "adFormat": "text",
  "headline": "Nike Running Shoes | Free Delivery & Returns",
  "description": "Shop the latest Nike running shoes. Members get free delivery.",
  "displayUrl": "nike.com",
  "textAssets": {"headline": "Nike Running Shoes | Free Delivery & Returns", "description": "Shop the latest Nike running shoes. Members get free delivery.", "visurl": "nike.com"},
  "imageUrl": null,
  "width": null,
  "height": null,
  "videoId": null,
  "videoUrl": null,
  "videoThumbnailUrl": null,
  "previewUrl": "https://displayads-formats.googleusercontent.com/ads/preview/content.js?...",
  "firstShown": "2025-06-02T00:00:00Z",
  "lastShown": "2025-10-12T00:00:00Z",
  "daysShown": 133,
  "targetDomain": "nike.com",
  "regions": null,
  "variationCount": null,
  "variations": null,
  "imageFileUrl": null,
  "adUrl": "https://adstransparency.google.com/advertiser/AR14188379519798214657/creative/CR10449491775734153217?region=anywhere",
  "searchType": "domain",
  "searchValue": "nike.com",
  "searchRegion": "anywhere",
  "scrapedAt": "2025-10-14T09:12:44Z",
  "markdown": "### Nike, Inc. - text ad CR10449491775734153217\n- Shown: 2025-06-02 to 2025-10-12 (133 days)\n- Domain: nike.com\n- Headline: Nike Running Shoes | Free Delivery & Returns\n- Description: Shop the latest Nike running shoes. Members get free delivery.\n- Display URL: nike.com\n- Transparency Center: https://adstransparency.google.com/advertiser/..."
}
```

(Values are illustrative.) Fields that don't apply (e.g. `videoUrl` on a text ad) are `null`, and every row has the same keys. With **Include ad details**, `regions` looks like `[{"regionCode": "FR", "regionName": "France", "firstShown": "...", "lastShown": "..."}]`. Export as JSON, CSV, Excel or HTML, or read the dataset through the API.

### Use with AI agents (MCP)

Add the actor to any MCP client (Claude Desktop, Claude Code, Cursor, ChatGPT connectors...) through the Apify MCP server:

```
https://mcp.apify.com/?actors=<username>/google-ads-transparency
```

Then ask, for example: *"List the video ads nike.com ran in France in the last 30 days and summarize their messages."* The `markdown` field gives the model a compact card per ad (advertiser, format, dates, headline, description, links), ready for prompts or a RAG index.

### Integrations

- **API**: start a run and read the dataset in one HTTP call (`run-sync-get-dataset-items`), or use the Python / JavaScript clients.
- **Make, Zapier, n8n**: use the Apify app / node to run the actor and pass each ad to the next step.
- **Google Sheets**: export the dataset as CSV, or use the Apify integration to append new ads automatically.
- **Schedules + webhooks**: run daily with `onlyNew: true` and send the new ads to Slack or email.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("<username>/google-ads-transparency").call(run_input={
    "domains": ["nike.com"], "region": "US", "maxAdsPerQuery": 50,
})
for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(ad["adFormat"], ad["headline"] or ad["imageUrl"] or ad["videoUrl"])
```

### Use cases

- **Competitor ad monitoring**: see every ad a competitor runs on Google Search, Display and YouTube and how long each one has been running. Long-running ads are usually the winners.
- **New-ad alerts**: schedule with `onlyNew` and get only the ads launched since the last run, at $0.0014 each.
- **Ad copy research**: collect real headlines and descriptions in your niche to brief copywriters or feed an AI model.
- **Creative inspiration**: pull image and video ads with direct links and sizes, and save images to your storage for mood boards.
- **Market entry checks**: filter by country to see who advertises in a market and since when.
- **Lead generation for agencies**: find brands that advertise on Google (so they have an active budget) and see what they run.
- **Compliance and brand protection**: spot ads pointing to your domain from accounts that aren't yours.

### FAQ

**Is there an official Google Ads Transparency API?**
No. Google publishes the Transparency Center as a website only. This actor reads the same public data and returns it as JSON, with no API key and no quota.

**Domain or advertiser: which should I use?**
A domain returns every ad pointing to that site, from all of the brand's accounts (several countries, agencies, resellers). An advertiser ID returns only that verified account's ads, including ads for other domains. A brand name is matched to the closest advertiser account(s). For brands with one account per country, raise **Advertisers per search term**.

**How does `onlyNew` work?**
The actor remembers which ads it delivered for each domain / advertiser + region, in your named key-value store `google-ads-transparency-state`. The next run skips those ads, and skipped ads are free. The first run returns everything. Delete the store to start over.

**Why is the headline empty on some ads?**
Image and video ads usually carry their text inside the image or video, so only text ads have `headline` and `description`. A few text ads use a format that can't be decoded; their `previewUrl` still shows the ad.

**Does the date filter use exact dates?**
An ad is kept if it was shown at some point in your range (`lastShown` ≥ start and `firstShown` ≤ end). Google keeps roughly the last year of history for most advertisers.

**Does the region filter work?**
Yes. The region is sent to Google the same way the website does it. With **Include ad details**, each ad also lists the exact countries where it ran.

**How many ads can I get?**
As many as the Transparency Center shows. For very large advertisers, the Transparency Center may stop paginating around 1,000 ads per query. To go further, split by region or format.

**Do I need a proxy?**
No. The default Apify datacenter proxy is included in your plan. If Google rate-limits those IPs, the actor retries with new IPs. If you allow it, it then finishes through the residential proxy (only the small JSON calls, never images).

**Is it legal?**
The Ads Transparency Center is a public Google service built so anyone can see who advertises. This actor reads only that public data, without login. You are responsible for how you use the data.

### Limits

- Ads disappear from the Transparency Center when Google removes them, and history is usually about one year.
- Google does not publish impressions or spend for commercial ads (only for political ads in some regions), so they are not in the output.
- Video ads come with the YouTube link, not a video file.
- Very large queries (tens of thousands of ads) take time, because calls to Google are paced to avoid blocks.
- Google can change its internal format at any time. The actor reads fields defensively, keeps delivering what it can, and never charges for empty rows.

# Actor input Schema

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

Websites whose ads you want, e.g. <code>nike.com</code>. Returns every ad that points to this domain, whatever the advertiser account.

## `searchTerms` (type: `array`):

Brand or company names, e.g. <code>Decathlon</code>. Each term is matched against the Transparency Center advertiser list; the best match(es) are scraped (see <b>Advertisers per search term</b>). A term that looks like a domain is searched as a domain.

## `advertiserIds` (type: `array`):

Transparency Center advertiser IDs, e.g. <code>AR14188379519798214657</code> (the part after <code>/advertiser/</code> in the URL).

## `startUrls` (type: `array`):

Paste URLs from adstransparency.google.com: an advertiser page (<code>/advertiser/AR...</code>), a single ad (<code>/advertiser/AR.../creative/CR...</code>) or a domain search (<code>?domain=nike.com</code>). A <code>region=</code> parameter in the URL overrides the Region field.

## `maxAdvertisersPerSearchTerm` (type: `integer`):

How many matching advertiser accounts to scrape for each name/keyword (big brands often have several accounts, one per country).

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

Only ads shown in this country. Keep <b>Anywhere</b> for all regions.

## `adFormat` (type: `string`):

Only text (Search), image (Display) or video (YouTube) ads.

## `startDate` (type: `string`):

Only ads still shown on or after this date (YYYY-MM-DD, or relative like <code>30 days</code>). Google keeps roughly the last year of history for most ads.

## `endDate` (type: `string`):

Only ads first shown on or before this date (YYYY-MM-DD, or relative like <code>7 days</code>). Leave empty for today.

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

Stop after this many ads for each domain, advertiser or search term. 0 = all ads available (the Transparency Center itself may stop paginating around 1,000 ads per query). You pay only for ads delivered.

## `includeDetails` (type: `boolean`):

One extra lookup per ad to add the regions where it was shown (with dates) and all its variations (every headline / image). Same price per ad, but the run is slower (about 0.5 s per ad).

## `extractAdContent` (type: `boolean`):

Decode the headline, description and display URL of text ads and the YouTube video of video ads. Turn off for the fastest listing (IDs, dates, previews only).

## `downloadImages` (type: `boolean`):

Download each image ad into the run's key-value store and add a permanent <code>imageFileUrl</code> link to the result. The Google image link (<code>imageUrl</code>) is always included anyway.

## `onlyNew` (type: `boolean`):

Return only ads not delivered by your previous runs of the same domain / advertiser / region. Ideal for a daily or weekly schedule: you pay only for new ads. The first run returns everything (baseline). Memory is kept in your named key-value store <code>google-ads-transparency-state</code> (delete it to start over).

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

How many ads are enriched at the same time. Calls to Google are paced anyway, so higher values rarely help.

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

Apify datacenter proxy by default (included in your plan).

## `residentialFallback` (type: `boolean`):

If Google blocks the datacenter IPs several times in a row, continue through Apify residential proxy (only the small JSON API calls use it, never images). Requires residential proxy access on your account.

## Actor input object example

```json
{
  "domains": [
    "nike.com"
  ],
  "searchTerms": [],
  "advertiserIds": [],
  "startUrls": [],
  "maxAdvertisersPerSearchTerm": 1,
  "region": "anywhere",
  "adFormat": "all",
  "maxAdsPerQuery": 20,
  "includeDetails": false,
  "extractAdContent": true,
  "downloadImages": false,
  "onlyNew": false,
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true
}
```

# Actor output Schema

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

All ads found, one item per ad (dataset).

## `files` (type: `string`):

Images saved when "Save images to storage" is on (key-value store).

## `runPage` (type: `string`):

No description

## `overview` (type: `string`):

Main results as a table (dataset view).

# 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"
    ],
    "searchTerms": [],
    "advertiserIds": [],
    "startUrls": [],
    "region": "anywhere",
    "maxAdsPerQuery": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("actose/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 = {
    "domains": ["nike.com"],
    "searchTerms": [],
    "advertiserIds": [],
    "startUrls": [],
    "region": "anywhere",
    "maxAdsPerQuery": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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