# Google Ads Transparency Scraper: Competitor Ads

> Google Ads Transparency Scraper is an Apify actor (API) by CheapAPI Labs. Every ad a domain or advertiser runs on Google, with format, preview and the dates it was shown. It costs $1.00 per 1,000 ads on the Apify Free plan and $0.51 on Gold, plus $0.0023 per search with results, billed through your Apify account with no API key. Compared with the most used Google Ads Transparency actor (about 4,400 users): 1,000 ads from 10 domains costs $1.02 on Free and $0.53 on Gold here and $1.90 and $0.90 there (Apify Store listing prices, checked September 2026). Apify platform usage is billed on top here.

- Page: https://cheapapilabs.com/actors/google-ads-transparency-scraper/
- Run on Apify: https://apify.com/cheapapi/google-ads-transparency-scraper
- Publisher: CheapAPI Labs (Apify username cheapapi)
- Main price: $1.00 per 1,000 ads on Free, $0.51 on Gold
- Our prices updated: 2026-10-30

## Prices per event (USD)

| Event | Free | Bronze | Silver | Gold |
|---|---:|---:|---:|---:|
| Search with results | $0.0023 | $0.0023 | $0.0023 | $0.0023 |
| Ad | $0.001 | $0.00068 | $0.00061 | $0.00051 |
| Advertiser | $0.001 | $0.00068 | $0.00061 | $0.00051 |
| Check or lookup | $0.0028 | $0.0028 | $0.0028 | $0.0028 |
| Fetched ad not delivered | $0.0001 | $0.0001 | $0.0001 | $0.0001 |

Platinum and Diamond pay the Gold price. Apify platform usage: billed separately by Apify.

## Call it from code

```bash
curl -X POST "https://api.apify.com/v2/acts/cheapapi~google-ads-transparency-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{"mode":"ads","targets":["nike.com"],"maxAdsPerTarget":100,"region":"anywhere","platform":"all","adFormat":"all","targetType":"auto","advertiserNameMatch":"best","monitoringName":"default","processingSpeed":"auto"}'
```

## Example output row

```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"
}
```

## Fields

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.

## 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 to $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://cheapapilabs.com/actors/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://cheapapilabs.com/actors/keyword-research-tool/) |
| Who ranks organically for a competitor's keywords | Different data source | [Domain SEO Analyzer](https://cheapapilabs.com/actors/domain-seo-analyzer/) |
| Ads on Meta, TikTok, LinkedIn | Google ads only |, |

## Limits

- See 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.

## 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). 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 to $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.
