# Google Ads Transparency Scraper (Ads by Advertiser or Domain) (`praguedatalab/google-ads-transparency-scraper`) Actor

Google Ads Transparency Center ads by brand, domain or advertiser ID: region, platform, format and date filters, image and preview links, days shown, optional per-country details. No proxy, no login. $0.30 per 1,000 ads.

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

## Pricing

from $0.30 / 1,000 ad (creative)s

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 — ads by advertiser, domain or brand

Scrape Google Ads Transparency Center ads for any advertiser, website or brand name, and get one clean row per ad: advertiser (country, verified identity), website, format (text, image, video), first and last day shown, days shown, image or preview link and the ad page. Filter by country, Google platform (Search, YouTube, Shopping, Maps, Play), format and dates. **$0.30 per 1,000 ads.** No browser, no login, no proxy needed.

### Quick start

Minimal input (the ads that point to nike.com and were shown in the US):

```json
{
    "queries": ["nike.com"],
    "region": "US",
    "maxAdsPerSearch": 50
}
```

More: two countries, only YouTube video ads, a date range, details for each ad, and the ads of one advertiser by ID:

```json
{
    "queries": ["adidas.com", "AR18378488041124659201"],
    "regions": ["DE", "FR"],
    "platforms": ["youtube"],
    "adFormat": "VIDEO",
    "startDate": "2026-09-01",
    "endDate": "2026-10-01",
    "maxAdsPerSearch": 300,
    "includeDetails": true
}
```

A query can be:

| You give | You get |
|---|---|
| a **domain** (`nike.com`, `https://www.nike.com/us`) | the ads that point to that website, whoever pays for them (agencies included) |
| an **advertiser ID** (`AR18378488041124659201`) | the ads of that advertiser |
| a **brand name** (`Nike`) | the ads of the advertisers whose name contains the word, the ones with the most ads first (`maxAdvertisersPerQuery`, default 5) |
| a **Transparency Center URL** (advertiser page, ad page, domain search) | the same, with the region, platform, format and date parameters of the URL |

For exact results use the domain or the advertiser ID. A brand name can match several unrelated advertisers.

### Compatible with the leading Actors

Switch by changing only the Actor ID. The input of both leaders is accepted as it is:

| Leader | Fields accepted |
|---|---|
| `scrapesage/google-ads-transparency-scraper` | `queries`, `domains`, `advertiserIds`, `startUrls`, `resultType` (`ads` / `advertisers`), `region` (code or English name), `platforms`, `adFormat` (`ALL`, `TEXT`, `IMAGE`, `VIDEO`), `startDate`, `endDate`, `maxAdsPerSearch`, `maxAdvertisersPerQuery`, `includeDetails` (free here), `detailConcurrency`, `onlyNewAds`, `monitorStoreName`, `includeRawData`, `urlsFromFile`, `proxyConfiguration` |
| `solidcode/ads-transparency-scraper` | `searchQuery` (keyword, domain or advertiser ID), `maxResults` (`0` = all), `platform` (`google_search`, `youtube`, `google_shopping`, `google_maps`, `google_play`), `region`, `dateFrom`, `dateTo` |

Output field names follow theirs: `creativeId`, `advertiserId`, `advertiserName`, `advertiserLegalName`, `advertiserCountry`, `advertiserVerified`, `domain`, `format`, `firstShown`, `lastShown`, `shownForDays` (also as `approxDaysShown`), `imageUrl`, `previewUrl`, `adUrl`, `region`, `matchedQuery`.

### Sample output row

A real row (nike.com, region US):

```json
{
    "creativeId": "CR08772523512997871617",
    "advertiserId": "AR16735076323512287233",
    "advertiserName": "Nike, Inc.",
    "advertiserLegalName": "Nike, Inc.",
    "advertiserCountry": "US",
    "advertiserVerified": true,
    "domain": "nike.com",
    "format": "TEXT",
    "platform": null,
    "firstShown": "2023-11-16T22:45:12.585Z",
    "lastShown": "2026-10-23T10:37:14.818Z",
    "shownForDays": 905,
    "approxDaysShown": 905,
    "imageUrl": "https://tpc.googlesyndication.com/archive/simgad/16152650943237359130",
    "previewUrl": null,
    "adUrl": "https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR08772523512997871617?region=US",
    "advertiserUrl": "https://adstransparency.google.com/advertiser/AR16735076323512287233?region=US",
    "region": "US",
    "matchedQuery": "nike.com",
    "scrapedAt": "2026-10-23T11:09:48.457Z"
}
```

With `includeDetails` each row also has `variationCount`, `variations`, `regionsShown` (country, first and last day, range of times shown, same per platform), `topic` and `adFundedBy`:

```json
{
    "variationCount": 4,
    "variations": [{ "imageUrl": "https://tpc.googlesyndication.com/archive/simgad/16098087104589060523", "previewUrl": null }],
    "regionsShown": [
        { "region": "ES", "firstShown": null, "lastShown": "2026-08-31", "timesShownLow": null, "timesShownHigh": 1000, "platforms": [{ "platform": "SEARCH", "timesShownLow": null, "timesShownHigh": 1000 }] }
    ],
    "topic": null,
    "adFundedBy": "Adidas America, Inc"
}
```

With `resultType: "advertisers"` each row is an advertiser: `advertiserId`, `name`, `legalName`, `countryCode`, `verified`, `approxAdCountLow`, `approxAdCountHigh`, `advertiserUrl`, `matchedQuery`.

### Input

| Field | Type | Description |
|---|---|---|
| `queries` | array of strings | Domains, advertiser IDs, brand names or URLs, one search each. |
| `domains`, `advertiserIds`, `startUrls` | arrays | Same as `queries`, split by kind. `startUrls` takes Transparency Center URLs with their own `region`, `platform`, `format`, `start-date`, `end-date` parameters. |
| `searchQuery` | string | One query (alias of solidcode). |
| `resultType` | string | `ads` (default) or `advertisers`. |
| `region` / `regions` | string / array | Country code (`US`, `DE`) or English name; `anywhere` for no filter. Default `US`. Each region is searched separately and the row says which. Alias: `country`. |
| `platforms` / `platform` | array / string | `search`, `youtube`, `shopping`, `maps`, `play` (also `google_search`…). Empty means all. |
| `adFormat` | string | `ALL` (default), `TEXT`, `IMAGE`, `VIDEO`. |
| `startDate`, `endDate` / `dateFrom`, `dateTo` | string | Ads shown in this period, `YYYY-MM-DD`, end day included. |
| `maxAdsPerSearch` / `maxResults` | integer | New ads saved per query and region, default 100, `0` = as many as exist. |
| `maxItems` | integer | Rows in total, all searches together. |
| `maxAdvertisersPerQuery` | integer | Advertisers kept for a brand name, default 5. |
| `includeDetails` | boolean | Variations, countries, topic and payer. One extra request per ad, about 1.5 s each. No extra charge. |
| `detailConcurrency` | integer | Detail requests in flight, default 2 (requests are spaced anyway). |
| `onlyNewAds`, `monitorStoreName` | boolean, string | Skip ads that an earlier run with the same store already saved. Run it on a schedule to get only new ads. |
| `includeRawData` | boolean | Adds Google's untouched answers in `raw`. |
| `urlsFromFile` | string | Link to a text file, one query per line. |
| `proxyConfiguration` | object | Not needed. Turn on the Apify proxy if Google asks for a captcha. |

### Output fields

| Field | Description |
|---|---|
| `creativeId` | Ad id (`CR…`). |
| `advertiserId` | Advertiser id (`AR…`). |
| `advertiserName` | Advertiser name as Google shows it. |
| `advertiserLegalName` | Legal name of a verified advertiser, otherwise `null`. |
| `advertiserCountry` | Country where the advertiser is based (ISO code). |
| `advertiserVerified` | `true` when Google says the advertiser verified its identity. |
| `domain` | Website the ad points to. |
| `format` | `TEXT`, `IMAGE` or `VIDEO`. |
| `platform` | `SEARCH`, `YOUTUBE`, `SHOPPING`, `MAPS` or `PLAY` when the search was limited to one platform, otherwise `null`. |
| `firstShown`, `lastShown` | First and last time the ad was shown, ISO 8601 UTC. |
| `shownForDays`, `approxDaysShown` | Days the ad was shown (not always consecutive). |
| `imageUrl` | Picture of the ad (text and image ads), otherwise `null`. |
| `previewUrl` | Script that renders the ad (display and video ads), otherwise `null`. |
| `adUrl`, `advertiserUrl` | Pages of the ad and of the advertiser in the Transparency Center. |
| `region` | Country searched, or `anywhere`. |
| `matchedQuery` | The input line that found the row. |
| `variationCount`, `variations`, `regionsShown`, `topic`, `adFundedBy` | With `includeDetails`. |
| `raw` | With `includeRawData`. |
| `scrapedAt` | When the row was saved. |

Advertiser rows (`resultType: "advertisers"`): `advertiserId`, `name`, `legalName`, `countryCode`, `verified`, `approxAdCountLow`, `approxAdCountHigh`, `advertiserUrl`, `matchedQuery`, `scrapedAt`.

### Pricing

Pay per event: **$0.0003 per ad** ($0.30 per 1,000) and the same per advertiser row. Details, raw data and every filter are included. Duplicates are not saved and not charged. Set `maxAdsPerSearch`, `maxItems` or a maximum cost per run to control the total. No platform usage is added on top.

### Limits and good to know

- **Speed.** Google returns 100 ads per request; the Actor sends about 1.5 requests per second, so 2,000 ads take about 30 seconds. `includeDetails` reads about 40 ads per minute because Google limits the detail requests; plan 25 minutes for 1,000 detailed ads.
- **Rate limit.** If Google answers "too many requests", the Actor waits and slows down by itself. If Google asks for a captcha the Actor never tries to solve it: it stops, keeps what it saved, and a run that saved nothing ends as failed with nothing charged. Turn on the Apify proxy in that case.
- **Platform.** Google's list does not say which platform showed an ad. Use the `platforms` filter to get one platform, or `includeDetails` to see the platforms per country.
- **Times shown.** Ranges are published for ads shown in the EU only. Where Google gives only an upper bound, `timesShownLow` is `null`.
- **Countries.** 243 countries and territories. Russia is not available: Google shows no ads there.
- **Advertisers are what Google publishes.** Most are companies, but some are sole traders or individuals who advertise, and Google lists them under the verified name they gave. The Actor only returns what the Transparency Center shows publicly and stores nothing else. Even a domain search can list an individual who advertises a brand's website (an affiliate, for example), and a brand name can match advertisers that are people. Check the rules that apply to your use (for example GDPR) before you keep or share personal names.
- The ads belong to their advertisers; Google publishes them for transparency.

# Actor input Schema

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

One search per line. A domain (<code>nike.com</code>) returns the ads that point to that website, whoever pays for them. An advertiser ID (<code>AR18378488041124659201</code>) returns the ads of that advertiser. A brand name (<code>Nike</code>) is matched to the advertisers with the most ads (see maxAdvertisersPerQuery). Page URLs of the Transparency Center and of websites work too.

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

Websites whose ads you want, one per line, for example <code>adidas.com</code>. Same as putting them in the first field.

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

Advertiser IDs (<code>AR</code> followed by 20 digits), one per line. You find them in the advertiser page URL of the Transparency Center.

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

Advertiser pages, ad pages or domain searches copied from <code>adstransparency.google.com</code>. The region, platform, format and date parameters of the URL are used for that URL.

## `resultType` (type: `string`):

<code>ads</code> saves the ads (event: ad). <code>advertisers</code> saves the advertisers instead (name, legal name, country, identity verified, approximate number of ads).

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

Country where the ads were shown: a two-letter code (<code>US</code>, <code>DE</code>, <code>FR</code>) or an English country name. <code>anywhere</code> searches every country. Default <code>US</code>. Alias: <code>country</code>.

## `regions` (type: `array`):

More than one country, one per line. Each is searched separately (the same ad in two countries gives two rows, with its own <code>region</code>).

## `platforms` (type: `array`):

Keep only ads shown on these Google platforms: <code>search</code>, <code>youtube</code>, <code>shopping</code>, <code>maps</code>, <code>play</code> (the spellings <code>google_search</code>, <code>google_maps</code>… work too). Empty means all platforms.

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

Keep only text, image or video ads.

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

Only ads shown on or after this day, YYYY-MM-DD. Alias: <code>dateFrom</code>.

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

Only ads shown on or before this day, YYYY-MM-DD. Alias: <code>dateTo</code>.

## `maxAdsPerSearch` (type: `integer`):

Ads saved for each query and each region (100 ads per request, newest first). <code>0</code> means as many as exist. You pay per ad saved. Alias: <code>maxResults</code>. Default 100.

## `maxItems` (type: `integer`):

Stops the run after this many rows (ads or advertisers), all searches together. You can also set a maximum cost per run in the run options.

## `maxAdvertisersPerQuery` (type: `integer`):

A brand name such as <code>Nike</code> matches many advertisers. The ones with the most ads are kept, up to this number.

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

Adds the variations of each ad, the countries where it ran with first and last day and the range of times shown, the topic Google gave it and who paid for it. One extra request per ad, so the run is slower. No extra charge.

## `detailConcurrency` (type: `integer`):

How many detail requests may be in flight at once. Requests are spaced out anyway to stay under Google's rate limit.

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

Skip ads that an earlier run with the same monitor store already saved. Use it with a schedule to get only the new ads of a brand each day.

## `monitorStoreName` (type: `string`):

Name of the key-value store that remembers the ads already seen (used by onlyNewAds). Letters, digits and dashes, at least 3.

## `includeRawData` (type: `boolean`):

Adds the untouched answer of Google for each ad in the <code>raw</code> field (keys are field numbers).

## `urlsFromFile` (type: `string`):

Link to a plain text file with one brand, domain, advertiser ID or URL per line. Lines starting with # are ignored.

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

Not needed: the endpoint answers requests from Apify servers. Turn on the Apify proxy only if Google asks for a captcha (the run then says so).

## `searchQuery` (type: `string`):

A keyword, domain or advertiser ID. Same as one line in the first field.

## `platform` (type: `string`):

One platform. Same as the Platforms field.

## `maxResults` (type: `integer`):

Same as Maximum ads per search. <code>0</code> means as many as exist.

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

Same as Shown from.

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

Same as Shown until.

## Actor input object example

```json
{
  "queries": [
    "nike.com"
  ],
  "domains": [],
  "advertiserIds": [],
  "startUrls": [],
  "resultType": "ads",
  "region": "US",
  "regions": [],
  "platforms": [],
  "adFormat": "ALL",
  "maxAdsPerSearch": 50,
  "maxItems": 1000,
  "maxAdvertisersPerQuery": 5,
  "includeDetails": false,
  "detailConcurrency": 2,
  "onlyNewAds": false,
  "monitorStoreName": "google-ads-transparency-seen",
  "includeRawData": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (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": [
        "nike.com"
    ],
    "domains": [],
    "advertiserIds": [],
    "startUrls": [],
    "resultType": "ads",
    "region": "US",
    "regions": [],
    "platforms": [],
    "adFormat": "ALL",
    "maxAdsPerSearch": 50,
    "maxItems": 1000,
    "maxAdvertisersPerQuery": 5,
    "includeDetails": false,
    "detailConcurrency": 2,
    "onlyNewAds": false,
    "monitorStoreName": "google-ads-transparency-seen",
    "includeRawData": false,
    "urlsFromFile": "",
    "proxyConfiguration": {
        "useApifyProxy": false
    },
    "searchQuery": "",
    "platform": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("praguedatalab/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 = {
    "queries": ["nike.com"],
    "domains": [],
    "advertiserIds": [],
    "startUrls": [],
    "resultType": "ads",
    "region": "US",
    "regions": [],
    "platforms": [],
    "adFormat": "ALL",
    "maxAdsPerSearch": 50,
    "maxItems": 1000,
    "maxAdvertisersPerQuery": 5,
    "includeDetails": False,
    "detailConcurrency": 2,
    "onlyNewAds": False,
    "monitorStoreName": "google-ads-transparency-seen",
    "includeRawData": False,
    "urlsFromFile": "",
    "proxyConfiguration": { "useApifyProxy": False },
    "searchQuery": "",
    "platform": "",
}

# Run the Actor and wait for it to finish
run = client.actor("praguedatalab/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 '{
  "queries": [
    "nike.com"
  ],
  "domains": [],
  "advertiserIds": [],
  "startUrls": [],
  "resultType": "ads",
  "region": "US",
  "regions": [],
  "platforms": [],
  "adFormat": "ALL",
  "maxAdsPerSearch": 50,
  "maxItems": 1000,
  "maxAdvertisersPerQuery": 5,
  "includeDetails": false,
  "detailConcurrency": 2,
  "onlyNewAds": false,
  "monitorStoreName": "google-ads-transparency-seen",
  "includeRawData": false,
  "urlsFromFile": "",
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "searchQuery": "",
  "platform": ""
}' |
apify call praguedatalab/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

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