# Google Ads Transparency Scraper — Competitor & Political Ads (`logical_vivacity/google-ads-transparency-scraper`) Actor

See every ad an advertiser is running. Search by brand name, website domain or advertiser ID and get each creative with format, first and last shown dates, days running, regions and images — plus spend, impressions and targeting for political ads where disclosure is required.

- **URL**: https://apify.com/logical\_vivacity/google-ads-transparency-scraper.md
- **Developed by:** [Logical Vivacity](https://apify.com/logical_vivacity) (community)
- **Categories:** Business, SEO tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 — Competitor Ads & Political Spend

**Every ad a competitor is running, with the dates that tell you which ones work.**

Google publishes the ads every verified advertiser is running. This Actor reads that library and hands you the creative: the image and video assets, the format, the landing domain, when each ad first appeared, when it was last seen, and **how many days it has been running** — which is the number that matters, because an ad still live after four years is an ad that pays for itself.

Give it a brand name, a website domain, or an advertiser ID.

**You pay per ad returned.** Advertisers with no ads, names that match nothing, and searches that fail cost you nothing.

***

### Try it in 30 seconds

Put these in **Brands, websites or advertiser IDs**, leave everything else alone, hit Start:

```
Nike
ramp.com
```

One table of ads out, with the advertiser's verified legal name attached to every row.

***

### Three ways in

**A brand name** — `Nike`, `Monday.com`, `Allbirds`. This Actor matches it to a registered advertiser and pulls that advertiser's ads. If a name matches several advertisers — regional entities, an agency buying on the brand's behalf, or someone pretending to be them — raise *Maximum advertisers per brand name* and get all of them.

**A website domain** — `ramp.com`, `stripe.com`. This is the precise one. It finds the ads pointing at that site regardless of what the advertiser calls itself, which matters because plenty of companies advertise under a legal name nobody would guess. A real run on `ramp.com` returned 3 live ads in text and image formats — one of them running for **1,649 days** — under the legal name *Ramp Business Corporation*.

**An advertiser ID** — `AR01234567890123456789`. Straight to that advertiser, no matching step. Use it once you've identified the advertiser you care about and want to re-run the same target on a schedule.

***

### What you get per ad

```jsonc
{
  "input": "ramp.com",

  "advertiserId": "AR13100033436137586689",
  "advertiserName": "Ramp",
  "legalName": "Ramp Business Corporation",   // who is legally paying for it
  "country": "US",
  "verificationStatus": "verified",
  "advertiserUrl": "https://adstransparency.google.com/advertiser/AR131000334…",

  "creativeId": "CR10463368325216862209",
  "format": "text",                            // image · text · video · html5
  "firstShown": "2021-03-18",
  "lastShown": "2026-09-16",
  "daysRunning": 1649,                         // a proven winner
  "regions": ["US", "CA", "GB"],
  "domain": "ramp.com",                        // where the click goes

  "imageUrls": ["https://…/creative.png"],
  "previewUrl": "https://displayads-formats.googleusercontent.com/…",
  "adUrl": "https://adstransparency.google.com/advertiser/AR13…/creative/CR10…",

  "totalAdsMin": 40,                           // how big this advertiser's library is
  "totalAdsMax": 50,

  "status": "ok",
  "scrapedAt": "2026-09-17T19:12:04Z"
}
```

With **Include ad details** switched on, each ad also carries:

```jsonc
{
  "variationCount": 7,                         // every version of this creative
  "imageUrls":   ["…", "…", "…"],              // the full asset set
  "previewUrls": ["…", "…"],
  "youtubeVideoIds": ["dQw4w9WgXcQ"],          // for video ads

  "disclosure": {                              // political / regulated ads only
    "impressionsMin": 100000,
    "impressionsMax": 1000000,
    "spendMin": { "currency": "USD", "amount": 50000 },
    "spendMax": { "currency": "USD", "amount": 100000 },
    "targeting": { "geoCriteriaIds": [2840], "targetsGender": true },
    "byRegion": [
      { "regionCriteriaId": 2840, "spend": 42000,
        "startDate": "2026-04-01", "endDate": "2026-06-30" }
    ]
  }
}
```

***

### Who uses this

**Competitive ad research** — what is the competition actually saying, in which formats, and which creative have they left running long enough to trust.

**Agencies** — audit a client's own live ads before a pitch or a handover, and put the competitor's creative in the same deck. One run per account, on a schedule.

**Political transparency researchers and journalists** — who is paying for political advertising, how much, to how many impressions, in which regions and over which dates. The disclosure fields are published data; most tools stop before them.

**Affiliate and ecommerce teams** — find the offers and angles that survive. Days-running plus landing domain tells you which funnels are earning their spend rather than which ones launched last week.

**Brand-protection teams** — search your own brand name across regions and find advertisers running ads on it who are not you: impersonators, unauthorised resellers, affiliates off-brief.

***

### What makes it different

**Search by website domain, not just brand name.** Most tools make you guess the advertiser's registered name. This Actor takes the domain and finds the ads pointing at it, which is how you find advertisers whose legal identity looks nothing like their marketing.

**All creative variations, not just the first one.** A single ad usually ships as a family — different sizes, different headlines, different images. Ad details returns the whole family with its asset URLs and YouTube video ids, which is the difference between "they run video" and having the videos.

**Political spend, impressions and per-region breakdown.** Where a region requires disclosure, this Actor extracts the impressions range, the spend range with currency, and spend per region with start and end dates. Competing actors return the ad and stop.

**Days-running on every row.** First-shown and last-shown dates turned into one number you can sort by. Sort descending and the top of your table is the competitor's proven creative; sort ascending and it's what they are testing right now.

**The advertiser's real identity.** Legal name, country and verification status on every row, so you can tell a verified brand from an unverified account using its name.

***

### Settings that matter

| Setting | What it does |
|---|---|
| **Brands, websites or advertiser IDs** | One per line — brand name, domain, or `AR…` ID, mixed freely |
| **Region** | Which country's ad library to read. 35 countries; the same brand returns different ads in each |
| **Maximum ads per advertiser** | Default 20. Raise it for big spenders |
| **Maximum advertisers per brand name** | Default 1. Raise it when a name matches several registered advertisers |
| **Ad formats** | Optional filter: image, text, video, HTML5 |
| **Include ad details** | Costs more. Adds all variations, YouTube ids, and political spend/impressions data |

Connection handling, pacing, retries and blocking are managed for you — there's nothing to configure and no proxy to set up.

### Automate it

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~google-ads-transparency-scraper/runs?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "advertisers": ["ramp.com", "brex.com", "Nike"],
        "region": "US",
        "maxAdsPerAdvertiser": 50,
        "adFormats": ["image", "video"],
        "includeAdDetails": true }'
```

Works with Make, Zapier, n8n, Google Sheets and the Apify API, and as an MCP tool for AI agents. Schedule a weekly run on a competitor set and you have a creative-change log without doing anything.

### Row statuses

| `status` | Meaning |
|---|---|
| `ok` | An ad was returned — charged |
| `no_ads` | The advertiser exists but runs no ads in this region — not charged |
| `not_found` | No advertiser matched that name or domain in this region — not charged |
| `error` | Temporarily unreachable — retry that search; not charged |

### FAQ

**Which regions are supported?**
35 countries, including the US, UK, Canada, Australia, Ireland, New Zealand, South Africa, most of western and northern Europe, Poland, Turkey, Israel, the UAE, India, Singapore, Japan, South Korea, Brazil, Mexico, Argentina, and Indonesia, the Philippines, Thailand and Vietnam. Pick one per run; run the same list again with a different region to compare.

**How far back does it go?**
As far back as the advertiser's oldest still-disclosed ad. In practice that runs to several years — the Ramp example above has a creative first shown in 2021. Ads that have been withdrawn from the public library are gone for everyone, including us.

**Can I download the images?**
Yes. Every row carries direct `imageUrls` and a `previewUrl`, and ad details adds the full asset set plus YouTube video ids. This Actor returns the links rather than the bytes, so you fetch only what you actually want to keep.

**Why do some ads show no landing page?**
Text ads and some formats don't publish a destination domain in the library, and video ads often point at a YouTube placement rather than a site. The `domain` field is filled where the library discloses it and left empty where it doesn't — rather than guessed.

**Is political spend data available everywhere?**
No, and that's the law, not a limitation. Spend and impressions are disclosed only for political and other regulated advertising, and only in regions that require it — the EU, the UK, the US and a handful of others. Ordinary commercial ads carry no `disclosure` block anywhere. When it's there, you get it.

**Do I need a Google account or API key?**
No.

***

### Terms of Use

This Actor collects publicly available information from Google's Ads Transparency Center — data Google publishes deliberately, so that anyone can see who is advertising and what they are saying.

You are responsible for using the results lawfully and in line with the applicable terms and regulations in your jurisdiction, including any rules on competitive intelligence, advertising and the use of political advertising data. Creative assets returned by this Actor are the intellectual property of the advertisers who made them; the links are provided for research and you are responsible for any use you make of the underlying material.

The data is provided without warranty of accuracy, completeness or fitness for a particular purpose. Disclosure ranges for spend and impressions are broad buckets published by Google, not measured figures — verify before you rely on them. This Actor is not affiliated with, endorsed by, or sponsored by Google.

***

*Missing a region, a format or a field you need?* Open an issue on the Actor's Issues tab.

# Actor input Schema

## `advertisers` (type: `array`):

One per line. Three things work: a brand name (Nike), a website domain (ramp.com) or a Google advertiser ID (AR01234567890123456789). Spotlight works out which you gave it. A domain search is the precise one — it finds the ads pointing at that site even when the advertiser's legal name looks nothing like the brand.

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

The country whose ad library you are reading. Ads are disclosed per country, so the same advertiser can return different ads — and different counts — in different regions. Run the same brand across several regions to see what it localises.

## `maxAdsPerAdvertiser` (type: `integer`):

How many ads to return for each advertiser found. Big spenders run thousands; start at 20 to see the shape of their creative, then raise it once you know what you want.

## `maxAdvertisersPerSearch` (type: `integer`):

Only used for brand-name searches. A name like "Nike" can match several registered advertisers — regional entities, agencies buying on the brand's behalf, and sometimes impersonators. Leave at 1 for the best match; raise it to see all of them side by side.

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

Optional. Leave empty for every format. Pick one or more to return only those — for example video only, when you are researching YouTube creative.

## `includeAdDetails` (type: `boolean`):

Off by default because it costs more — it opens each ad individually. Turn it on and every ad also carries all of its creative variations, the full set of image and preview assets, any YouTube video ids, and — for political and regulated ads in regions that require disclosure — the impressions range, spend range, per-region spend with start and end dates, and demographic targeting flags. This is the only way to get the spend and impressions data.

## Actor input object example

```json
{
  "advertisers": [
    "Nike",
    "ramp.com"
  ],
  "region": "US",
  "maxAdsPerAdvertiser": 20,
  "maxAdvertisersPerSearch": 1,
  "includeAdDetails": false
}
```

# Actor output Schema

## `results` (type: `string`):

Every ad an advertiser is running, with how long each has been live.

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

The same rows as a spreadsheet-style table, with the most useful columns first.

# 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 = {
    "advertisers": [
        "Nike",
        "ramp.com"
    ]
};

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

# Run the Actor and wait for it to finish
run = client.actor("logical_vivacity/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 '{
  "advertisers": [
    "Nike",
    "ramp.com"
  ]
}' |
apify call logical_vivacity/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

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