# Google Ads Transparency Scraper — Domain, Advertiser & Keyword (`innolabs/google-ads-transparency-scraper`) Actor

Google Ads Transparency scraper and API: all ads by domain, advertiser ID or name — creative ID, format, first/last shown, regions, ad text, landing URL, image/video URLs.

- **URL**: https://apify.com/innolabs/google-ads-transparency-scraper.md
- **Developed by:** [Tristan Leroux](https://apify.com/innolabs) (community)
- **Categories:** Marketing, Lead generation
- **Security:** Limited permissions
- **Stats:** 4 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## 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.
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 — Ads by Domain, Advertiser & Keyword

Get every Google ad a company runs — on Search, YouTube, Maps, Play and Shopping — straight from the
public Google Ads Transparency Center. Search by website domain, advertiser ID or advertiser name and
get ad format, first/last shown dates, regions, ad text, landing URLs, YouTube videos and EU impression
ranges. No login, no API key; export to JSON, CSV or Excel.

### What does Google Ads Transparency Scraper do?

Google publishes every ad shown on its network in the [Ads Transparency Center](https://adstransparency.google.com).
This scraper turns it into a clean dataset:

- **Ads by domain** — enter `nike.com` and get all ads promoting that site, across every advertiser
  account (brand, resellers, agencies).
- **Ads by advertiser** — paste an advertiser ID (`AR…`) or advertiser page URL to get all their ads,
  or an ad page URL (`…/creative/CR…`) to get one ad with full details.
- **Advertiser search** — look up advertisers by name or keyword (`hubspot`, `nike`) and get their
  name, ID, country and approximate number of ads. Optionally scrape their ads too.
- **Filters** — region (any country or anywhere), Google platform (Search, YouTube, Maps, Play,
  Shopping), format (text, image, video) and a shown-between date range.
- **Ad details (optional)** — headline, description, long headline, call to action, display URL,
  landing page URL, YouTube video link, duration and channel, image URLs, all ad variations,
  per-region last-shown dates, and for EU/EEA regions first-shown dates, impression ranges per
  platform and the advertiser's audience targeting.

### Use cases

- **Competitive intelligence:** see which campaigns a competitor runs, since when, in which countries
  and on which Google platforms.
- **Agencies and media buyers:** collect creative inspiration — headlines, video ads and display
  creatives — for a pitch or a category audit.
- **Ad-spy and monitoring tools:** schedule daily runs to detect new ads of tracked brands
  (`firstShown`) and ads that stopped running (`lastShown`).
- **Lead generation:** find companies actively advertising in a niche and country — active Google
  advertisers have marketing budget.
- **Brand protection:** spot resellers and affiliates advertising your domain or brand name.
- **Researchers and journalists:** analyse political, health or finance advertisers with EU impression
  ranges and targeting data.

### How much does it cost?

You pay per result; there is no monthly fee and platform usage is included.

| Event | What you pay for | Free plan | Paid plans (from) |
| --- | --- | --- | --- |
| `ad` | One ad in the dataset (with or without details) | $1.50 per 1,000 | $1.00 per 1,000 |
| `advertiser` | One advertiser row from an advertiser search | $1.50 per 1,000 | $1.00 per 1,000 |

Examples:

- All recent ads of 5 competitor domains, 200 ads each = 1,000 ads → **$1.50** on the Free plan,
  $1.00 on Gold and higher.
- Advertiser search for 20 keywords, 10 advertisers each = 200 advertisers → **$0.30** on the
  Free plan.

The Apify Free plan includes $5 monthly credit, enough for about 3,300 ads every month.

### How to use Google Ads Transparency Scraper

1. Open the Actor in Apify Console and click **Try for free**.
2. Enter one or more **Advertiser domains** (e.g. `nike.com`), **Advertiser IDs or URLs**, or
   **Advertiser search** terms.
3. Optionally pick a **Region**, **Google platform**, **Ad format** and date range, and tick
   **Include ad details** for ad text, landing URLs, videos and EU impressions.
4. Set **Max ads per target** and **Max items**, then click **Start**.
5. Download the results as JSON, CSV or Excel, or read them through the API (see below).

### Input

| Field | Type | Description |
| --- | --- | --- |
| `domains` | list | Advertiser websites, e.g. `nike.com` (any URL form works). |
| `advertiserIds` | list | `AR…` advertiser IDs, advertiser page URLs, or ad page URLs (`…/creative/CR…`). |
| `searchTerms` | list | Advertiser names or keywords to look up. |
| `includeAdsFromSearch` | boolean | Also scrape the ads of every advertiser found by a search term. Default `false`. |
| `maxAdvertisersPerSearch` | integer | Advertisers kept per search term (1–50). Default `10`. |
| `region` | string | 2-letter country code (`US`, `GB`, `DE`…) or `anywhere`. Default `anywhere`. |
| `platform` | string | `ALL`, `SEARCH`, `YOUTUBE`, `MAPS`, `PLAY` or `SHOPPING`. Default `ALL`. |
| `format` | string | `ALL`, `TEXT`, `IMAGE` or `VIDEO`. Default `ALL`. |
| `startDate`, `endDate` | date | Only ads shown in this range (`YYYY-MM-DD`). |
| `includeDetails` | boolean | Add ad text, URLs, video, variations, regions, EU impressions and targeting. Default `false`. |
| `maxAdsPerTarget` | integer | Max ads per domain / advertiser. Default `100`. |
| `maxItems` | integer | Max dataset rows for the whole run. Default `1000`. |
| `proxyConfiguration` | object | Default: Apify residential proxy. |

Example:

```json
{
    "domains": ["nike.com"],
    "advertiserIds": ["https://adstransparency.google.com/advertiser/AR01625195283841286145"],
    "searchTerms": ["hubspot"],
    "region": "US",
    "format": "VIDEO",
    "includeDetails": true,
    "maxAdsPerTarget": 50
}
```

### Output

One row per ad (`"type": "ad"`) and per advertiser found by search (`"type": "advertiser"`). Real ad
row from a run with `includeDetails` (arrays shortened):

```json
{
    "type": "ad",
    "advertiserId": "AR01625195283841286145",
    "advertiserName": "Shopify Inc.",
    "creativeId": "CR16547359735549001729",
    "format": "VIDEO",
    "domain": "shopify.com",
    "firstShown": "2025-12-23T17:21:17Z",
    "lastShown": "2026-11-02T14:50:27Z",
    "daysActive": 315,
    "totalDaysShown": 315,
    "region": "US",
    "platform": "ALL",
    "previewUrl": "https://displayads-formats.googleusercontent.com/ads/preview/content.js?client=ads-integrity-transparency&creativeId=789539858111&…",
    "imageUrl": null,
    "adUrl": "https://adstransparency.google.com/advertiser/AR01625195283841286145/creative/CR16547359735549001729?region=US",
    "sourceType": "domain",
    "source": "shopify.com",
    "regions": ["ES", "US", "FR", "RO", "IT"],
    "regionStats": [
        {"region": "ES", "firstShown": "2026-01-29", "lastShown": "2026-01-29", "impressionsMin": 0, "impressionsMax": 1000,
         "platforms": [{"platform": "YOUTUBE", "impressionsMin": 0, "impressionsMax": 1000}]},
        {"region": "US", "firstShown": null, "lastShown": "2026-11-02", "impressionsMin": null, "impressionsMax": null, "platforms": []}
    ],
    "impressionsMin": 0,
    "impressionsMax": 1000,
    "platformStats": [{"platform": "YOUTUBE", "impressionsMin": 0, "impressionsMax": 1000}],
    "audienceSelection": {
        "demographics": "included",
        "locations": "included",
        "contextualSignals": "included and excluded",
        "topicsOfInterest": "included and excluded"
    },
    "headline": "Build your business with Shopify",
    "longHeadline": "Start, run and grow your business from anywhere with the Shopify app",
    "description": "Join millions selling with Shopify",
    "displayUrl": "shopify.com",
    "landingUrl": "https://www.shopify.com/mobile",
    "youtubeVideoId": "CzTnPa8oSf0",
    "youtubeUrl": "https://www.youtube.com/watch?v=CzTnPa8oSf0",
    "videoThumbnailUrl": "https://i.ytimg.com/vi/CzTnPa8oSf0/hqdefault.jpg",
    "videoDuration": "0:17",
    "channelName": "Shopify",
    "variationCount": 5
}
```

Advertiser row from an advertiser search:

```json
{
    "type": "advertiser",
    "advertiserId": "AR13611357312189988865",
    "advertiserName": "HubSpot",
    "country": "US",
    "adCountMin": 100,
    "adCountMax": 200,
    "region": "US",
    "advertiserUrl": "https://adstransparency.google.com/advertiser/AR13611357312189988865?region=US",
    "searchTerm": "hubspot",
    "relatedDomains": ["hubspot.es", "hubspot.com", "hubspot.net", "eduhubspot.com", "thehubspots.com"]
}
```

Field notes:

- `firstShown` / `lastShown` are UTC timestamps; `daysActive` is the span between them,
  `totalDaysShown` the number of days Google reports the ad as shown.
- `region` and `platform` echo your filters; `regions` (with details) lists every country where the ad ran.
- Many older text ads are archived by Google as screenshots: they come with `imageUrl` but no
  `headline`/`description`.
- Impression ranges, per-region first-shown dates and `audienceSelection` are published by Google only
  for EU/EEA regions; elsewhere they are `null`.
- `adTexts` holds the visible text lines of ad templates that have no separate headline fields
  (e.g. Shopping and some Search ads).
- With details on, every detail field is present (possibly `null`) so CSV/Excel columns stay stable.
  If one ad's details cannot be loaded, the ad is still saved with `detailsError`.

### Integrations and API

Run the Actor and get the results with one API call:

```bash
curl -X POST "https://api.apify.com/v2/acts/innolabs~google-ads-transparency-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domains": ["nike.com"], "region": "US", "maxAdsPerTarget": 50}'
```

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("innolabs/google-ads-transparency-scraper").call(
    run_input={"domains": ["nike.com", "adidas.com"], "format": "VIDEO", "includeDetails": True}
)
for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(ad["advertiserName"], ad["firstShown"], ad.get("headline"), ad.get("youtubeUrl"))
```

- **Make, Zapier, n8n:** use the Apify app/node to start the Actor and map dataset rows to Google
  Sheets, Airtable, Slack or your CRM.
- **Scheduling:** create a schedule in Apify Console (e.g. daily) to track competitors' new ads;
  compare `creativeId`s or filter by `firstShown`.
- **AI agents:** the Actor is available as a tool through the Apify MCP server at
  https://mcp.apify.com, so Claude, ChatGPT or Cursor can look up a company's Google ads on demand.

### FAQ

#### Is it legal to scrape the Google Ads Transparency Center?

The scraper reads only public information that Google publishes for transparency, the same data anyone
can see on adstransparency.google.com without logging in. It collects no personal data about users.
Check the rules that apply to your use case and jurisdiction.

#### Do I need proxies?

No setup needed. Google throttles busy IP addresses, so the Actor uses Apify residential proxy by
default and automatically retries a throttled request from a new IP. Ad previews for details are
downloaded directly and use the proxy only when needed. Proxy traffic is included in the price.

#### How many ads can I get?

The Transparency Center lists up to tens of thousands of ads for large brands (the log shows Google's
estimate per target, e.g. `50000–60000` for nike.com). Use `maxAdsPerTarget` and `maxItems` to control
volume and cost. Ads come in the order the Transparency Center shows them.

#### How do I get only new ads?

Schedule the Actor and keep `creativeId`s you have already seen, or use `startDate` to fetch only ads
shown since your last run and compare `firstShown`.

#### What happens if a domain or advertiser fails?

Each target is processed independently. A failing or invalid target is reported in the run's `SUMMARY`
record (key-value store) and the others continue. If every target fails, the run fails with a clear
message instead of finishing with an empty dataset. A domain with no ads simply returns no rows.

#### Why are some ads missing text?

Google archives many older text ads as images. For those you get `imageUrl` (the archived screenshot)
but no `headline`/`description`. Video, display and current search ads come with their text.

### Limits

- Data is limited to what Google publishes in the Ads Transparency Center: no ad spend, impression
  ranges only for EU/EEA regions, and landing URLs only where the ad preview contains them.
- `includeDetails` makes about two extra requests per ad, so it is much slower than the list mode
  (about 50 ads per second without details, about 1–2 ads per second with details).
- Ad text comes from the first variation of each ad; all variations are listed in `variations`.
- Advertiser search returns up to 50 best matches per term.

# Changelog

This Actor's version history is a separate document: https://apify.com/innolabs/google-ads-transparency-scraper/changelog.md

# Actor input Schema

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

Websites whose ads you want (e.g. nike.com). Every ad Google shows in the Ads Transparency Center for that domain is returned, across all advertisers that promote it.

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

Advertiser IDs (AR…) or Ads Transparency Center URLs: advertiser pages (https://adstransparency.google.com/advertiser/AR…) return all their ads; ad pages (…/advertiser/AR…/creative/CR…) return that single ad with full details.

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

Look up advertisers by name or keyword (e.g. 'nike', 'hubspot'). Each match is saved as an advertiser row with ID, legal name, country and approximate ad count.

## `includeAdsFromSearch` (type: `boolean`):

For each advertiser found by a search term, also scrape its ads (up to 'Max ads per target' each).

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

How many advertiser matches to keep per search term (best matches first).

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

Only ads shown in this country. 'Anywhere' covers all regions.

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

Only ads shown on this Google surface.

## `format` (type: `string`):

Only ads of this format.

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

Only ads shown on or after this date (YYYY-MM-DD). Leave empty for no lower bound.

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

Only ads shown on or before this date (YYYY-MM-DD). Leave empty for today.

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

Open every ad for headline, description, call to action, display and landing URL, YouTube video, image URLs, all variations, per-region first/last shown dates, impression ranges (EU) and audience targeting. Slower: two extra requests per ad.

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

Cap per domain / advertiser.

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

Hard cap on dataset rows (ads + advertisers) for the whole run. The run stops cleanly when reached.

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

Google blocks busy datacenter IPs for the Ads Transparency Center, so residential proxy is the default; a blocked request is retried from a new IP. List mode uses about 1 KB of proxy traffic per ad, ad details about 20–60 KB per ad.

## `debug` (type: `boolean`):

Verbose logs for development.

## Actor input object example

```json
{
  "domains": [
    "nike.com"
  ],
  "includeAdsFromSearch": false,
  "maxAdvertisersPerSearch": 10,
  "region": "anywhere",
  "platform": "ALL",
  "format": "ALL",
  "includeDetails": false,
  "maxAdsPerTarget": 100,
  "maxItems": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "debug": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

All items produced by the run, one JSON object per record.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "domains": [
        "nike.com"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("innolabs/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 = {
    "domains": ["nike.com"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("innolabs/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 '{
  "domains": [
    "nike.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call innolabs/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

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