# Google Ads Transparency Scraper — Ads by Domain (`cheapapi/google-ads-transparency-scraper`) Actor

Scrape Google Ads Transparency Center: all ads of an advertiser or domain with creative ID, format, preview, first/last shown. Region & date filters.

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

## Pricing

Pay per event + usage

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 - Competitor Ads

Get every ad a company runs on Google — Search, YouTube, Shopping, Maps and Play — straight from the Google Ads Transparency Center: advertiser, verification status, creative ID, format, preview image, and when each ad was first and last shown. Search by domain, advertiser name or advertiser ID, one row per ad — or just check which domains run ads at all.

**All fees at a glance (event fees; Apify platform usage billed separately):** $0.0023 per advertiser/domain search that returns ads · $0.00051–$0.001 per ad or advertiser row (Gold → Free) · $0.0028 per Check (Only-check line, advertiser-name lookup, or a search with nothing to deliver) · $0.0001 per fetched ad not delivered (repeats in "Only new ads"). Details under [Pricing](#pricing).

**Why this Actor**

- **Ad metadata, not ad copy:** you get advertiser, creative ID, format, preview image/link, dates and a Transparency Center link per ad. The ad's headline/text, landing page URL and impressions are **not included** (see [Not included](#not-included)); if you need those, some pricier Actors in the comparison below return them.

- **From $0.51 per 1,000 ads** on Gold plans ($1.00 on Free) plus $0.0023 per advertiser or domain searched. Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005). See the dated comparison below.

- **Check 1,000 domains for ads for $2.80** with "Only check whether each domain/advertiser runs ads": one row per line with `hasAds`, total ads, format mix and first/last shown dates ($0.0028 per checked line).

- **Only new ads since the last run:** schedule the same list and get just the creatives that appeared since the previous run. Ads you already received are skipped and cost only $0.0001 each (they still have to be fetched to be recognized).

- **Up to 700 ads per advertiser or domain**, with filters for region (249 countries), platform, ad format and date range. **25 fields per ad**, including a stable row `id`, preview image size, days the ad ran and a direct link to the ad in the Transparency Center.

- **Small runs are processed instantly** (up to 20 advertisers or domains, no queue); bigger batches go through a queue and usually take a few minutes.

- **Failed searches are retried automatically** (up to 2 more times) and are not charged if they still fail (the one exception, a request that got no answer at all, is explained under [Pricing](#pricing)).

- **No login, no API key, no proxies.** Enter a domain and press Start.

### Compared with alternatives

Typical run: **1,000 ads from 10 domains** (100 ads each).

| Option | Free plan | Gold plan | Ad text / impressions | Only-check mode (1 row per domain) | Only new ads since last run | Failed searches retried |
|---|---|---|---|---|---|---|
| Most-used Actor (~4,400 users), $1.90 / $0.90 per 1,000 ads | $1.90 + $0.00005 start fee | $0.90 + $0.00005 start fee | ✓ ad copy (per its listing) | not stated | not stated | not stated |
| Second most-used Actor (~2,100 users), $1.48 / $0.77 per 1,000 ads | $1.48 + $0.00005 start fee | $0.77 + $0.00005 start fee | ✓ ad copy + impressions (per its listing) | not stated | not stated | not stated |
| Third most-used Actor (~2,100 users), $1.50 / $0.80 per 1,000 results | $1.50 + $0.001 start fee | $0.80 + $0.001 start fee | not stated | ✗ | ✗ | not stated |
| Fourth most-used Actor (~1,400 users), $0.002 per ad | $2.00 | $2.00 | not stated | ✓ ($0.003 per advertiser row) | ✓ | not stated |
| Smaller Actor (~790 users), $1.80 / $0.70 per 1,000 ads | $1.80 | $0.70 | ✓ impressions (per its listing) | not stated | not stated | not stated |
| Smaller Actor (~740 users), $1.50 per 1,000 results | $1.50 + $0.00005 start fee | $1.50 + $0.00005 start fee | not stated | ✗ | ✗ (compare runs yourself) | not stated |
| **This Actor** ($0.0023 per search + per-ad price) | **$1.02** | **$0.53** | ✗ (metadata + preview only) | ✓ ($0.0028 per checked line) | ✓ (repeats $0.0001 each) | ✓ |

Prices from public Apify Store listings, checked September 2026. The amounts above are event fees only; for this Actor, Apify platform usage is billed separately by Apify on top (at the default 256 MB a small run typically uses about $0.001–$0.005); the second Actor's listing also bills platform usage to the user. Platinum and Diamond plans pay the Gold price here; the listed rivals charge the same as on Gold on those plans. For this typical run our event fees are 30.9% lower than the cheapest of these options on Free ($1.023 vs. $1.480) and 30.8% lower than the cheapest of the three most-used on Gold ($0.533 vs. $0.770, start fees included). **Rivals that return the ad text or impressions give richer data per ad** — if you need the copy itself, compare on that basis, not on price alone. We are not the cheapest in every configuration: the ~790-user Actor above costs $0.70 on Gold (we are 23.9% lower there, not 30%), and a few small Actors (under 200 users) list lower per-ad prices, some well under $0.50 per 1,000 ads. Our $0.0023 search fee is charged per domain that returns ads, so a run that fetches only one or two ads from each of many domains can cost less with a per-result Actor; for those, "Only check" mode ($0.0028 per line, no per-ad fee) is usually the cheaper way to screen domains. Store prices change; check the current listing before you decide.

### Not included

| Not included | Why | Use instead |
|---|---|---|
| Ad headline/text copy and landing page URL | The Transparency Center archive we read gives the preview image or preview link, not the text or target URL | For the text and URL of ads shown on Google Search for a keyword: [Google SERP Scraper](https://apify.com/cheapapi/google-serp-scraper) (`paidResults`) |
| Impressions, spend, targeting, regions an ad ran in | Not provided for regular (non-political) ads | — |
| Keyword CPC and competition | Not part of the ads archive | [Keyword Research Tool](https://apify.com/cheapapi/keyword-research-tool) |
| Who ranks organically for a competitor's keywords | Different data source | [Domain SEO Analyzer](https://apify.com/cheapapi/domain-seo-analyzer) |
| Ads on Meta, TikTok, LinkedIn | Google ads only | — |

### What data you get

The Actor has three modes (**What do you want to get?**). Each mode writes its own kind of row.

#### Ads mode — one row per ad (default)

| Field | Type | Example |
|---|---|---|
| `id` | string | `3f9c1e0a7b2d4c5e6f70` (stable: same ad, input and filters = same `id` in every run) |
| `input` | string | `nike.com` |
| `inputType` | string | `domain`, `advertiserId` or `advertiserName` |
| `position` | integer | `1` |
| `advertiserId` | string | `AR04489795172984422401` |
| `advertiserName` | string | `Example Store Ltd` (the advertiser's verified legal name, which Google shows as the ad's title) |
| `verified` | boolean | `true` (Google has verified the advertiser's identity) |
| `creativeId` | string | `CR00276381635123871745` |
| `format` | string | `text`, `image` or `video` |
| `adUrl` | string | Link to this ad in the Transparency Center |
| `previewImageUrl` | string | `https://tpc.googlesyndication.com/archive/simgad/1594…` |
| `previewImageWidth` / `previewImageHeight` | integer | `348` / `134` |
| `previewUrl` | string | Google's preview link for the ad, when it has one (often for video ads) |
| `firstShown` / `lastShown` | ISO date-time | `2026-03-20T21:01:38.000Z` |
| `daysShown` | integer | `188` |
| `advertiserPageUrl` | string | `https://adstransparency.google.com/advertiser/AR0448…` |
| `totalAdsFound` | integer | `92` (the total Google reports for this search) |
| `region`, `platform`, `adFormatFilter`, `dateFrom`, `dateTo` | string | The filters used for this row |
| `scrapedAt` | ISO date-time | `2026-09-28T15:55:20.549Z` |

#### Only check mode — one summary row per line

| Field | Type | Example |
|---|---|---|
| `id` | string | stable ID of the line + filters |
| `input`, `inputType` | string | `nike.com`, `domain` |
| `checkStatus` | string | `adsFound`, `noAds`, `advertiserNotFound`, `failed` or `invalidInput` |
| `hasAds` | boolean | `true` (`false` = no ads for these filters; `null` = the line could not be checked) |
| `totalAdsFound` | integer | `92` (Google's total for the search) |
| `adsChecked` | integer | `40` (the most recent ads looked at, up to 40) |
| `advertiserCount`, `advertiserIds`, `advertiserNames` | integer, array, array | `1`, `["AR0448…"]`, `["Example Store Ltd"]` |
| `verified` | boolean | `true` if any advertiser in the checked ads is verified |
| `formats`, `formatCount` | array, integer | `["image","text","video"]`, `3` |
| `textAds`, `imageAds`, `videoAds` | integer | `32`, `5`, `3` (among the checked ads) |
| `firstShownEarliest`, `lastShownLatest` | ISO date-time | `2026-01-20T16:22:37.000Z`, `2026-09-24T22:09:42.000Z` |
| `lastShownDaysAgo` | integer | `4` (days between the latest ad and the run) |
| `transparencyUrl` | string | Transparency Center page for the domain or advertiser |
| `region`, `platform`, `adFormatFilter`, `dateFrom`, `dateTo`, `scrapedAt` | string | Filters used and time of the run |

The format counts and the date range come from the checked ads (the 40 most recent). `totalAdsFound` is Google's full total.

#### Find advertisers mode — one row per advertiser account

| Field | Type | Example |
|---|---|---|
| `id` | string | stable ID of search term + advertiser + region |
| `searchTerm` | string | `apple` |
| `position` | integer | `1` |
| `resultType` | string | `advertiser`, `multiAccountAdvertiser` (a brand with several accounts) or `domain` (a matching website) |
| `advertiserId` | string | `AR03186575737440174081` (the first account for multi-account brands) |
| `advertiserName` | string | `Apple Inc.` |
| `verified` | boolean | `true` |
| `advertiserCountry` | string | `US` |
| `approxAdsCount` | integer | `500` (Google's rounded ad count) |
| `advertiserIds` | array | `["AR0318…", "AR1599…"]` — paste these into Ads mode |
| `accounts` | array | Only on `multiAccountAdvertiser` rows: each account's `advertiserId`, `country`, `verified`, `approxAdsCount`, `advertiserPageUrl` |
| `domain` | string | `apple.com` (only on `domain` rows) |
| `advertiserPageUrl` | string | Advertiser page, or the domain search page for `domain` rows |
| `region`, `scrapedAt` | string | Region used and time of the run |

#### Why some fields are empty (null by mode)

All three row types share one dataset, so a CSV export has every column. `id`, `region` and `scrapedAt` are filled on every row. Columns that belong to another mode stay empty:

| Field | Ads rows | Only-check rows | Find-advertisers rows |
|---|---|---|---|
| `creativeId`, `format`, `adUrl`, `previewImage*`, `previewUrl`, `firstShown`, `lastShown`, `daysShown`, `position` | filled | empty | only `position` |
| `hasAds`, `checkStatus`, `adsChecked`, `formats`, `textAds`/`imageAds`/`videoAds`, `firstShownEarliest`, `lastShownLatest` | empty | filled | empty |
| `searchTerm`, `resultType`, `advertiserCountry`, `approxAdsCount`, `accounts`, `domain` | empty | empty | filled |
| `advertiserIds` | empty | filled | filled |

Within a mode, a field is `null` when Google has no value: for example `previewImageUrl` for ads that only have a `previewUrl`, `advertiserName`/`advertiserId` on `domain` rows, and all counts on only-check rows with `checkStatus` `failed` or `invalidInput`. Each dataset view (Ads, Ad timeline, Ad check, Advertisers) shows only the columns of its mode.

### How to use

1. Open the Actor in the Apify Console.
2. Choose **What do you want to get?** — every ad (default), **Only check whether each domain/advertiser runs ads**, or **Find advertisers**.
3. Enter one or more **domains, advertiser names or advertiser IDs** (for example `nike.com`). You can also paste links copied from adstransparency.google.com.
4. Optionally set **Maximum ads per advertiser or domain** (default 100, up to 700) and a **Region**.
5. Many domains already in another run's dataset (for example a company list with a `website` column)? Put its ID into **Source dataset ID** (Advanced) instead of pasting them.
6. Press **Start** and download the results as JSON, CSV, Excel, XML or HTML from the **Output** tab, or use the API.

Ready-to-paste input:

```json
{
    "targets": ["nike.com", "AR03186575737440174081", "Booking.com"],
    "maxAdsPerTarget": 200,
    "region": "US",
    "platform": "youtube",
    "adFormat": "video",
    "dateFrom": "2026-01-01"
}
```

Check a list of domains for ads (one row per domain):

```json
{ "mode": "presence", "targets": ["nike.com", "adidas.com", "example-bakery.com"], "region": "US" }
```

Load domains from the dataset of an earlier run (e.g. a company list with a `website` column), plus one typed line:

```json
{ "mode": "presence", "sourceDatasetId": "<DATASET_ID>", "targets": ["nike.com"] }
```

Find advertiser IDs first:

```json
{ "mode": "advertisers", "targets": ["apple", "samsung.com"] }
```

#### API

cURL:

```bash
curl -X POST "https://api.apify.com/v2/acts/cheapapi~google-ads-transparency-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"targets": ["nike.com"], "maxAdsPerTarget": 100, "region": "anywhere"}'
```

JavaScript (`apify-client`):

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_TOKEN>' });
const run = await client.actor('cheapapi/google-ads-transparency-scraper').call({
    targets: ['nike.com', 'adidas.com'],
    maxAdsPerTarget: 100,
    region: 'US',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]);
```

Python (`apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("cheapapi/google-ads-transparency-scraper").call(run_input={
    "targets": ["nike.com", "adidas.com"],
    "maxAdsPerTarget": 100,
    "region": "US",
})
for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(ad["advertiserName"], ad["format"], ad["firstShown"], ad["lastShown"])
```

### Use cases

- **Competitor ad research:** see every creative a competitor runs, which formats they use and how long each ad has been live.
- **Creative inspiration:** collect preview images of long-running ads (a high `daysShown` usually means the ad performs well).
- **Market and regional monitoring:** compare a brand's ads across countries, platforms (YouTube vs. Search) and time ranges.
- **Lead generation for agencies:** run "Only check" on a list of prospect domains to see who advertises on Google right now (`hasAds`, `lastShownDaysAgo`), how much (`totalAdsFound`) and in which formats — for $0.0023 per advertiser.
- **Brand protection:** detect advertisers using your brand name or domain.
- **New-campaign alerts:** turn on "Only new ads since the last run" and schedule the run weekly — each run returns only the creatives that appeared since the previous one.

### Advanced options

| Option | Default | What it does |
|---|---|---|
| **What do you want to get?** (`mode`) | `ads` | `ads` = one row per ad; `presence` = only check whether each line runs ads (one summary row per line, looks at the 40 most recent ads); `advertisers` = find advertiser accounts by name or domain |
| **Maximum ads per advertiser or domain** (`maxAdsPerTarget`) | `100` | 1–700 (Ads mode only) |
| **Region** (`region`) | `anywhere` | Only ads shown in this country (ISO code), or all regions |
| **Platform** (`platform`) | `all` | `googleSearch`, `youtube`, `googleShopping`, `googleMaps`, `googlePlay` |
| **Ad format** (`adFormat`) | `all` | `text`, `image`, `video` |
| **Shown from / Shown until** (`dateFrom`, `dateTo`) | empty | Date range, YYYY-MM-DD, from 2018-05-31. Set one date and the other is filled in for you |
| **Region by name** (`location`) | empty | Full location name, e.g. `United Kingdom`. Overrides Region |
| **Coordinates** (`coordinates`) | empty | `latitude,longitude`. Overrides Region and Region by name |
| **Treat every line as** (`targetType`) | `auto` | Force `domain`, `advertiserId` or `advertiserName` (e.g. for a brand called `Booking.com`) |
| **Advertiser name matching** (`advertiserNameMatch`) | `best` | `best` = exact name match, otherwise the top result; `all` = combine every account found (up to 25) |
| **Combine advertiser IDs into one list** (`combineAdvertiserIds`) | `false` | Up to 25 IDs per list, charged as one search |
| **Source dataset ID** (`sourceDatasetId`) | empty | Reads domains / advertiser IDs from another run's dataset: `advertiserId` (or `advertiserIds`), otherwise the first domain in `domain`, `website` or `url`. Merged with the lines above, duplicates removed, up to 50,000 rows. Google Maps/Search links are ignored. `RUN_SUMMARY.sourceDataset` shows rows read, values found and rows skipped |
| **Only new ads since the last run** (`onlyNewAds`) | `false` | Ads mode only. Delivers only ads not delivered in an earlier run for the same line and monitoring name; repeats are not delivered and cost $0.0001 each (Ad check); a line with nothing new costs one Check ($0.0028) |
| **Monitoring name** (`monitoringName`) | `default` | Each name keeps its own list of seen ads (e.g. one per watch list or schedule) |
| **Processing speed** (`processingSpeed`) | `auto` | `auto`, `instant`, `fast`, `standard`. Same price. Runs with up to 20 searches always run instantly; bigger runs use the fast queue (about a minute) |
| **Maximum wait** (`maxWaitMinutes`) | `60` | Searches that don't finish in time are listed in the run summary. They may already have been processed, so each costs one Check ($0.0028), plus $0.0001 per requested ad in Ads mode |

#### Monitoring: only new ads since the last run

1. Enter your competitors' domains or advertiser IDs in Ads mode and turn on **Only new ads since the last run**.
2. Optionally give the list a **Monitoring name** (e.g. `competitors-us`).
3. Save it as a task and add a **Schedule** (e.g. every Monday).

The first run delivers every ad (up to your maximum per line) and remembers their creative IDs. Every later run delivers only creatives that were not delivered before. A line with no new ads delivers nothing and costs one Check ($0.0028) plus one Ad check ($0.0001) per repeat that was fetched and skipped — the ads have to be fetched to know they are repeats. Seen creative IDs are kept per line and monitoring name in your account's key-value store `google-ads-transparency-new-ads` and are forgotten after 365 days without being seen. Delete that store (or use a new monitoring name) to start over. `RUN_SUMMARY` shows `onlyNewAds.newAds` and `onlyNewAds.repeatsSkipped`.

Only ads within **Maximum ads per advertiser or domain** (most recent first) are compared, so set it high enough to cover the ads an advertiser launches between two runs.

### Output example

Example output, Ads mode (one row per ad):

```json
{
    "id": "3f9c1e0a7b2d4c5e6f70",
    "input": "nike.com",
    "inputType": "domain",
    "position": 1,
    "advertiserId": "AR04489795172984422401",
    "advertiserName": "Example Store Ltd",
    "verified": true,
    "creativeId": "CR16364962713689915393",
    "format": "text",
    "adUrl": "https://adstransparency.google.com/advertiser/AR04489795172984422401/creative/CR16364962713689915393?region=GB",
    "previewImageUrl": "https://tpc.googlesyndication.com/archive/simgad/16027894890232583589",
    "previewImageWidth": 348,
    "previewImageHeight": 134,
    "previewUrl": null,
    "firstShown": "2026-04-09T06:25:20.000Z",
    "lastShown": "2026-09-26T13:01:34.000Z",
    "daysShown": 170,
    "advertiserPageUrl": "https://adstransparency.google.com/advertiser/AR04489795172984422401",
    "totalAdsFound": 92,
    "region": "anywhere",
    "platform": "all",
    "adFormatFilter": "all",
    "dateFrom": null,
    "dateTo": null,
    "scrapedAt": "2026-09-28T15:55:20.549Z"
}
```

Example output, Only check mode (one row per line):

```json
{
    "id": "a41d07c9e2b85f6031c4",
    "input": "examplebrand.com",
    "inputType": "domain",
    "checkStatus": "adsFound",
    "hasAds": true,
    "totalAdsFound": 92,
    "adsChecked": 40,
    "advertiserCount": 1,
    "advertiserIds": ["AR04489795172984422401"],
    "advertiserNames": ["Examplebrand OU"],
    "verified": true,
    "formats": ["image", "text", "video"],
    "formatCount": 3,
    "textAds": 32,
    "imageAds": 5,
    "videoAds": 3,
    "firstShownEarliest": "2026-01-20T16:22:37.000Z",
    "lastShownLatest": "2026-09-24T22:09:42.000Z",
    "lastShownDaysAgo": 4,
    "transparencyUrl": "https://adstransparency.google.com/?region=anywhere&domain=examplebrand.com",
    "region": "anywhere",
    "platform": "all",
    "adFormatFilter": "all",
    "dateFrom": null,
    "dateTo": null,
    "scrapedAt": "2026-09-29T05:06:29.348Z"
}
```

Example output, Find advertisers mode (a brand with two accounts):

```json
{
    "id": "c7e2a90d5f1b3864e0a2",
    "searchTerm": "apple",
    "position": 1,
    "resultType": "multiAccountAdvertiser",
    "advertiserId": "AR03186575737440174081",
    "advertiserName": "Apple Inc.",
    "verified": true,
    "advertiserCountry": "US",
    "approxAdsCount": 500,
    "advertiserIds": ["AR03186575737440174081", "AR15992851274060005377"],
    "accounts": [
        { "advertiserId": "AR03186575737440174081", "country": "US", "verified": true, "approxAdsCount": 300, "advertiserPageUrl": "https://adstransparency.google.com/advertiser/AR03186575737440174081" },
        { "advertiserId": "AR15992851274060005377", "country": "US", "verified": true, "approxAdsCount": 200, "advertiserPageUrl": "https://adstransparency.google.com/advertiser/AR15992851274060005377" }
    ],
    "domain": null,
    "advertiserPageUrl": "https://adstransparency.google.com/advertiser/AR03186575737440174081",
    "region": "US",
    "scrapedAt": "2026-09-29T05:06:29.348Z"
}
```

The key-value store record `RUN_SUMMARY` lists how many advertisers or domains returned ads, returned none or failed, and why.

### Pricing

**Apify Free plan:** Apify does not pay developers for usage on its Free plan, so on the Free plan this Actor can be used for up to **$0.25 of results per calendar month** — enough to try it on a small input. When the allowance is used up, the run ends with a clear message (not an error). Any paid Apify plan removes the limit; prices are the same.

Pay per event. Every lookup in Google's ad library is a paid request for us, so every lookup is charged: a search that delivers rows costs the Search fee plus one fee per row; a lookup that ends without delivered rows costs one Check. Invalid lines and searches the data service rejects are free. Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005); the prices and examples in this section are event fees only.

| Event | Free | Bronze | Silver | Gold, Platinum, Diamond |
|---|---|---|---|---|
| Search with results (per advertiser, domain or ID list that delivers ads; per Find-advertisers search that delivers advertisers) | $0.0023 | $0.0023 | $0.0023 | $0.0023 |
| Ad (per row, Ads mode) | $0.001 | $0.00068 | $0.00061 | $0.00051 |
| Advertiser (per row, Find advertisers mode) | $0.001 | $0.00068 | $0.00061 | $0.00051 |
| Check or lookup (see below) | $0.0028 | $0.0028 | $0.0028 | $0.0028 |
| Fetched ad not delivered (Ad check, see below) | $0.0001 | $0.0001 | $0.0001 | $0.0001 |

**When a Check ($0.0028) is charged:** each line in **Only check** mode (with or without ads); each advertiser-**name** lookup (found or not — a name therefore costs one Check more than a domain or ID); a domain, ID list or Find-advertisers search that finds nothing for your filters; a line with nothing new in "Only new ads" mode; and a request that got no answer or never finished (it may still have been processed).

**When an Ad check ($0.0001) is charged:** per ad that was fetched but not delivered — in practice the repeats skipped by "Only new ads since the last run". In the rare case that an ad list request got no answer at all, it is also charged once per requested ad (up to your "Maximum ads per advertiser or domain"), because those ads may have been fetched. With default settings and normal answers you never pay an Ad check.

Your Apify plan sets the price automatically.

**Worked examples**

| Run | Free | Bronze | Silver | Gold+ |
|---|---|---|---|---|
| 1,000 ads from 10 domains (100 each): 10 searches + 1,000 ads | $1.02 | $0.70 | $0.63 | $0.53 |
| All ads of one domain (700 ads): 1 search + 700 ads | $0.70 | $0.48 | $0.43 | $0.36 |
| Only check 1,000 domains (with or without ads): 1,000 checks | $2.80 | $2.80 | $2.80 | $2.80 |
| Weekly "only new ads" for 10 domains, 100 ads each, 5 new per domain: 10 searches + 50 ads + 950 ad checks | $0.17 | $0.15 | $0.15 | $0.14 |
| Advertiser name, 100 ads: 1 check + 1 search + 100 ads | $0.11 | $0.07 | $0.07 | $0.06 |
| Find advertisers for 20 brand names (about 10 accounts each): 20 searches + 200 advertisers | $0.25 | $0.18 | $0.17 | $0.15 |

For example on a **Bronze** plan, 1,000 ads from 10 domains cost 10 × $0.0023 + 1,000 × $0.00068 = **$0.70**; on **Silver** the same run costs 10 × $0.0023 + 1,000 × $0.00061 = **$0.63**. If one of those 10 domains had no ads for your filters, it would cost one Check ($0.0028) instead of a Search plus ads. Platform usage is billed separately by Apify.

Set a **maximum charge per run** in the run options. The Actor plans around that limit (it lowers the number of ads per line, or skips the last lines) and stops cleanly when it is reached. Skipped lines are listed in `RUN_SUMMARY`.

### Integrations

- **Make, Zapier, n8n:** start runs and pass the rows on with the Apify apps for each platform.
- **Google Sheets:** export the dataset directly, or use the Google Sheets integration to append rows after every run.
- **Webhooks:** get a call to your own URL when a run succeeds or fails.
- **Schedules:** check competitors daily or weekly with "Only new ads since the last run", or a prospect list with `hasAds`/`lastShownDaysAgo` in Only check mode.
- **API and MCP:** call the Actor from your code with the Apify API or client libraries, or from AI assistants through the Apify MCP server.

### FAQ

**Is there a limit on the Apify Free plan?** Yes: up to $0.25 of this Actor's results per calendar month, enough to try it. Apify pays developers nothing for Free-plan usage while our data costs are real, so this keeps the Actor sustainable. Runs that reach the allowance stop cleanly and keep everything collected so far; the allowance resets on the 1st of the month. Any paid Apify plan has no limit.

**Is it legal?** The Google Ads Transparency Center is a public library that Google publishes so anyone can see who is advertising. This Actor only collects that public information. You are still responsible for how you use the data, so follow the laws that apply to you.

**How fresh is the data?** Each run collects it live, at that moment. `lastShown` tells you when Google last served each ad.

**Why did I get fewer ads than the advertiser has?** You can get up to 700 ads per advertiser or domain per run. Region, platform, format and date filters narrow the list, and Google itself only lists ads it has archived. A maximum charge per run can also lower the number. To go past 700, split the run with date ranges or regions.

**How do I only check whether a list of domains runs ads?** Choose "Only check whether each domain/advertiser runs ads". You get one row per line with `hasAds`, `totalAdsFound`, the format mix and first/last shown dates, and you pay $0.0028 per checked line, with or without ads (two Checks for an advertiser name: the name lookup and the check).

**Does it include the ad text, landing page or impressions?** No (see [Not included](#not-included)). You get the preview image or preview link, which usually shows the ad as it looked.

**Domain, advertiser name or advertiser ID — which should I use?** A domain gives every ad that points to that website, even across several advertiser accounts. An advertiser ID is the most precise. A name is convenient, but it runs an extra lookup, which is charged as one Check ($0.0028), found or not. Big brands often use several advertiser accounts: Find advertisers mode lists them all, and "Advertiser name matching: all" combines up to 25 of them.

**Why is `previewImageUrl` empty for some ads?** Some ads, mostly video and some text ads, have only a `previewUrl` (Google's interactive preview) and no static image.

**Can I monitor competitors automatically?** Yes. Turn on "Only new ads since the last run", save your input as a task and add a Schedule (e.g. every Monday). Each run then returns only new creatives; repeats cost $0.0001 each and a line with nothing new costs one Check ($0.0028). Connect a webhook or Google Sheets to receive the new rows.

**What happens when a search fails?** Searches that fail because the data service is busy or the network drops are retried automatically (up to 2 more times, with a short wait). If a search still fails, it is listed in `RUN_SUMMARY` and not charged. The one exception: a request that was sent but got no answer at all (the connection dropped, or a queued search never finished within your maximum wait) is not resent, because it may already have been processed — it costs one Check ($0.0028), plus $0.0001 per requested ad in Ads mode.

**Why was I charged a Check or Ad check?** A Check ($0.0028) means we looked something up that did not end in delivered rows: a line in Only check mode, an advertiser-name lookup, a line without ads (or without new ads) for your filters, or a request that got no answer. Ad checks ($0.0001) are ads that were fetched but not delivered, almost always repeats skipped by "Only new ads since the last run". `RUN_SUMMARY` shows `checksCharged` and `adChecksCharged`, and the reason per line under `problems`. To keep costs down, set a maximum charge per run in the run options, lower "Maximum ads per advertiser or domain", and use domains or advertiser IDs instead of names. Apify platform usage (compute) is billed separately by Apify on top of these fees (at 256 MB a small run typically uses about $0.001–$0.005) and is shown per run in Apify Console.

**Where do I get help?** Open an issue on the Actor's Issues tab and include your run ID. We read and answer every issue.

### Limitations

- See [Not included](#not-included): no ad text, landing page URL, impressions or targeting.
- Up to 700 ads per advertiser, domain or combined ID list per run.
- Only check mode looks at the 40 most recent ads of each line: `totalAdsFound` is Google's full total, but the format counts and `firstShownEarliest` cover only those 40 ads. It always runs through the fast queue, so results take about a minute.
- An advertiser name that matches several companies uses the best match (or all matches if you choose that). For exact results, use the domain or the advertiser ID.
- Data comes from Google's own public archive, so it only covers ads Google shows there. Political and some policy-restricted ads may appear differently.
- The ad order and the `totalAdsFound` count come from Google and can change from run to run.

### Privacy

The Actor collects only what Google publishes in the Ads Transparency Center: advertisers' verified business names, IDs, countries and their ads. It does not collect data about people who see or click ads. Some advertisers are individuals who advertise under their own name; handle such names according to the data protection rules that apply to you (e.g. GDPR).

# Actor input Schema

## `mode` (type: `string`):

<b>Ads</b>: every ad of an advertiser or domain. <b>Only check</b>: one row per line with hasAds, total ads, formats and first/last shown dates, charged as one check ($0.0028) per checked line, with or without ads. <b>Find advertisers</b>: search the Transparency Center for advertiser accounts (e.g. to get their advertiser IDs).

## `targets` (type: `array`):

One per line. Accepts a domain (<code>nike.com</code>), an advertiser name (<code>Nike, Inc.</code>; needs one extra lookup, charged as a check of $0.0028), an advertiser ID (<code>AR13752565271262920705</code>) or a link from adstransparency.google.com (advertiser page or domain search). In "Find advertisers" mode, enter names or domains to search for. Required (the run stops with a clear message if it is empty) unless you set a <b>Source dataset ID</b> (Advanced).

## `maxAdsPerTarget` (type: `integer`):

Stop after this many ads for each line (most recent first as ordered by Google). Up to 700. Not used in "Only check" mode, which always looks at the 40 most recent ads.

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

Only ads shown in this country. "Anywhere" returns ads from all regions.

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

Only ads shown on this Google platform.

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

Only ads of this format.

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

Only ads shown on or after this date (YYYY-MM-DD, not earlier than 2018-05-31). If you set only one date, the other one is filled in automatically.

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

Only ads shown on or before this date (YYYY-MM-DD).

## `location` (type: `string`):

Full location name instead of the Region list, e.g. <code>United Kingdom</code> or <code>London,England,United Kingdom</code>. Leave empty to use Region.

## `coordinates` (type: `string`):

Latitude,longitude, e.g. <code>52.52,13.405</code>. The ads shown in the region around this point are returned. Overrides Region and Region by name.

## `targetType` (type: `string`):

Automatic detection works for almost everything. Force "Advertiser name" for names that look like domains (e.g. <code>Booking.com</code> as an advertiser name).

## `advertiserNameMatch` (type: `string`):

For advertiser names: which advertiser accounts to list ads for. Big brands often run several accounts; "All" combines them.

## `combineAdvertiserIds` (type: `boolean`):

Collect the ads of up to 25 advertiser IDs together as a single list (one search instead of one per ID). "Maximum ads" then applies to the combined list.

## `sourceDatasetId` (type: `string`):

Optional. Pick (or paste the ID of) an Apify dataset from an earlier run — for example a list of companies with a <code>website</code> column, or an earlier run of this Actor. From each row the Actor takes <code>advertiserId</code> (or <code>advertiserIds</code>), otherwise the first domain found in <code>domain</code>, <code>website</code> or <code>url</code>. Values are merged with the lines above and duplicates are removed. Up to 50,000 rows are read; rows without a domain or advertiser ID are skipped and counted in the run summary.

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

Ads mode only. Remembers the creative IDs delivered for each advertiser/domain and delivers only ads that were not delivered before. Repeats are <b>not delivered</b>; each fetched repeat costs one ad check ($0.0001), and a line without new ads costs one check ($0.0028) plus its ad checks. The first run delivers everything. Schedule the same input daily or weekly to get just the new creatives.

## `monitoringName` (type: `string`):

Each name keeps its own list of seen ads. Use one name per watch list (e.g. <code>competitors-us</code>) so separate schedules do not affect each other. Max 100 characters.

## `processingSpeed` (type: `string`):

How each search is processed. All speeds have the same price. Runs with up to 20 searches are always processed instantly. Automatic is best for almost every run.

## `maxWaitMinutes` (type: `integer`):

Searches not finished within this time are reported in the run summary. They may already have been processed, so each costs one check ($0.0028), plus $0.0001 per requested ad in Ads mode.

## Actor input object example

```json
{
  "mode": "ads",
  "targets": [
    "nike.com"
  ],
  "maxAdsPerTarget": 100,
  "region": "anywhere",
  "platform": "all",
  "adFormat": "all",
  "targetType": "auto",
  "advertiserNameMatch": "best",
  "combineAdvertiserIds": false,
  "onlyNewAds": false,
  "monitoringName": "default",
  "processingSpeed": "auto",
  "maxWaitMinutes": 60
}
```

# Actor output Schema

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

No description

## `presence` (type: `string`):

No description

## `advertisers` (type: `string`):

No description

## `runSummary` (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 = {
    "mode": "ads",
    "targets": [
        "nike.com"
    ],
    "maxAdsPerTarget": 100,
    "region": "anywhere",
    "platform": "all",
    "adFormat": "all",
    "targetType": "auto",
    "advertiserNameMatch": "best",
    "monitoringName": "default",
    "processingSpeed": "auto"
};

// Run the Actor and wait for it to finish
const run = await client.actor("cheapapi/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 = {
    "mode": "ads",
    "targets": ["nike.com"],
    "maxAdsPerTarget": 100,
    "region": "anywhere",
    "platform": "all",
    "adFormat": "all",
    "targetType": "auto",
    "advertiserNameMatch": "best",
    "monitoringName": "default",
    "processingSpeed": "auto",
}

# Run the Actor and wait for it to finish
run = client.actor("cheapapi/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 '{
  "mode": "ads",
  "targets": [
    "nike.com"
  ],
  "maxAdsPerTarget": 100,
  "region": "anywhere",
  "platform": "all",
  "adFormat": "all",
  "targetType": "auto",
  "advertiserNameMatch": "best",
  "monitoringName": "default",
  "processingSpeed": "auto"
}' |
apify call cheapapi/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

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