# Google Ads Scraper — Ads Transparency by Domain or Advertiser (`actor-forge/google-ads-scraper`) Actor

Google Ads scraper for competitor research: every Search, YouTube, Display and Shopping ad a domain or advertiser runs, read from the public Google Ads Transparency Center. Format, first/last shown, regions, impressions, ad copy, images, video. $0.60 per 1,000 ads.

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

## Pricing

from $0.60 / 1,000 ad results

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 Scraper — Ads Transparency by Domain or Advertiser

Google Ads scraper for competitor research: every Search, YouTube, Display and Shopping ad a domain or advertiser runs, read from the public Google Ads Transparency Center. Format, first/last shown, regions, impressions, ad copy, images, video. $0.60 per 1,000 ads.

A **Google Ads scraper** for competitor research: give it a competitor's **domain** (nike.com), an **advertiser name** (HubSpot) or a Google advertiser ID, and get one clean row for **every ad Google lists for them**: Search (text), YouTube (video), Display and Shopping (image) ads. Each row has the advertiser (company name, ID, country), creative ID, format, **first and last shown dates**, days running, countries, impression ranges, best-effort **ad copy** (headline and description), image and video URLs, landing domain and a link to the ad's public page. Filter by country, date range and format.

**Where the data comes from:** the public **Google Ads Transparency Center** (adstransparency.google.com), Google's own ad library. It is the same source every "Google Ads Scraper" on the Store reads. It is **not** a scraper of live Google search results pages: it shows which ads an advertiser runs and where, not the ad positions for a keyword.

**Monitor competitors' new ads:** switch on *Only new ads since the last run*, schedule it daily, and each run returns just the ads that appeared since the previous run. Already-seen ads are skipped and **never charged**.

**Honest and polite by design:** plain HTTP with an **honest user agent** naming this actor, no browser imitation, no proxy rotation, at most 2 requests at a time. If Google answers with a **CAPTCHA** or its "unusual traffic" page, the run **stops at once**, keeps the ads already delivered, and charges nothing for blocked requests. If that happens before any ad is delivered, the dataset gets one free status row saying so ("Google temporarily rate-limited; no ads delivered, nothing charged").

**$0.60 per 1,000 ads**, about a third of the leading Google Ads scrapers ($1.48 to $1.90 per 1,000). 256 MB, no browser.

### What data does it return?

Every run outputs clean, schema-validated rows like these:

| advertiserName | format | firstShown | lastShown | regions | landingDomain | previewUrl |
| --- | --- | --- | --- | --- | --- | --- |
| Nike, Inc. | text | 2022-11-30 | 2026-10-19 | US | nike.com | https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR00144196208338927617 |
| INITIATIVE MEDIA B.V. | video | 2023-10-17 | 2026-10-19 | FR, BE, DE, IT, ES, … | nike.com | https://adstransparency.google.com/advertiser/AR11154049584043393025/creative/CR03397377851928870913 |
| Hubspot, Inc. | text | 2025-11-03 | 2026-10-19 | US, DE, FR, IN, BR, … | hubspot.com | https://adstransparency.google.com/advertiser/AR10072600183532683265/creative/… |
| Argos Limited | text | 2025-… | 2026-10-19 | GB | argos.co.uk | https://adstransparency.google.com/advertiser/AR08556219150266007553/creative/CR07375270183734083585 |

### How much does it cost?

Transparent pay-per-event pricing — you only pay for what you get, and the
actor **always respects your run budget**: set a maximum total charge and it
stops cleanly at the cap instead of overrunning.

| Event | Price | Charged | Worked example |
| --- | --- | --- | --- |
| `ad-result` | $0.0006 | per ad delivered | 100 ads = $0.06; 1,000 ads = $0.60; a daily monitor returning ~20 new ads = $0.012 a day |
| `ad-detail` | $0.001 | per ad, only when 'Include ad details' is on (one extra lookup: regions, impressions, ad copy) | 100 ads with details = $0.06 + $0.10 = $0.16 |
| `apify-actor-start` | $0.00005 | per run per GB of memory (platform start fee) | One run at 256 MB = $0.0000125 |

### Input options

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `domains` | array | no | — | Competitor websites, e.g. nike.com. Returns the ads Google lists for that domain in the Ads Transparency Center (Search, YouTube, Display and Shopping), from the brand itself and from agencies or resellers advertising it. |
| `advertiserNames` | array | no | `[]` | Company names as shown in the Ads Transparency Center, e.g. HubSpot, Argos Limited. Exact name matches are used (a brand's several legal entities are all kept); otherwise the closest advertiser with the most ads. |
| `advertiserIds` | array | no | `[]` | Google advertiser IDs (AR… from an adstransparency.google.com/advertiser/AR… link). |
| `regions` | array | no | `[]` | Only ads shown in these countries, as two-letter codes (US, GB, DE, FR…). Empty = anywhere. |
| `dateFrom` | string | no | — | Only ads shown on or after this date (YYYY-MM-DD). |
| `dateTo` | string | no | — | Only ads shown on or before this date (YYYY-MM-DD). |
| `formats` | array | no | `[]` | Only these formats. Empty = all formats (text covers Search ads; image and video cover Display, YouTube and Shopping creatives). |
| `maxAdsPerAdvertiser` | integer | no | `100` | How many ads to read for each domain, advertiser name or advertiser ID, newest first as the Transparency Center lists them. |
| `maxResults` | integer | no | `1000` | Stop after this many ads across all searches. You pay per ad delivered ($0.60 per 1,000). |
| `includeDetails` | boolean | no | `false` | One extra lookup per ad: countries shown, impression ranges and first/last shown per country, plus best-effort headline/description text. Charged as ad-detail ($1 per 1,000). |
| `onlyNewSinceLastRun` | boolean | no | `false` | Remember every ad delivered in a named key-value store (ads-seen-\<monitor name>) and return only ads not seen before. Schedule the actor daily to get a feed of competitors' new ads; already-seen ads are skipped and never charged. |
| `monitorName` | string | no | `"default"` | Name of the seen-ads memory used by 'Only new ads'. Use one name per schedule (e.g. uk-competitors) so separate watch lists don't share state. |
| `proxyConfiguration` | object | no | `{"useApifyProxy":false}` | Not needed: the Transparency Center is public. Leave off unless you have your own reason to route requests through a proxy. The actor never rotates proxies to get around a block. |

### Limits & honest notes

- Source: the public Google Ads Transparency Center only. This actor does **not** scrape live Google search results pages (no keyword ad positions, no SERP ads) and does not use the Google Ads API (no spend, clicks or keywords).
- No CAPTCHA solving and no protection bypass. If Google serves a CAPTCHA or its "unusual traffic" page (or keeps answering 429/403), the run stops at once, keeps the ads already delivered, and says so in the status message and RUN_SUMMARY. Blocked requests are never charged; a run stopped before any ad is delivered returns one free status row. Google can do this to automated traffic from busy IP ranges, so re-run later.
- Requests use an honest user agent naming this actor, with no browser imitation and no proxy rotation. You can set your own proxy for your own reasons; the default is none. Data comes from the same keyless JSON calls the public Transparency Center page makes (its robots.txt has no rules), paced at most 2 at a time, 0.8-2 s apart, with backoff on errors.
- Ad copy (headline/description) needs 'Include ad details' and is best-effort: many Google text ads are published only as a rendered snapshot image (returned as previewImageUrl), and image ads have no text.
- There is no ad-text keyword search in the Transparency Center: search by domain, advertiser name or advertiser ID. A domain search returns ads from every advertiser that advertises that domain (agencies and resellers included).
- Advertiser country is filled for advertiser-name searches (from Google's advertiser search); domain and ID searches leave it empty.
- Advertisers are businesses. Where Google lists a verified individual as the advertiser, only the name Google itself publishes is returned. No other personal data is collected.
- 'Max ads per domain / advertiser' counts ads read, newest first, so a daily monitor stays fast and cheap. Already-seen ads (monitoring), filtered-out formats and errors are never charged.
- Respects your run budget: set a maximum total charge and the actor stops cleanly at the cap.

### Related ActorForge actors

- [Google Ads Transparency Scraper — Competitor Ads | $0.60/1K](https://apify.com/actor-forge/ads-transparency) — the same actor and data under its Transparency Center name
- [Website Change Monitor](https://apify.com/actor-forge/website-change-monitor) — watch competitors' landing pages change
- [Tech Stack Detector](https://apify.com/actor-forge/tech-stack-detector) — see which ad and analytics tags a competitor runs

### Changelog

- **2026-10-22** — Initial release as a separate Google Ads Scraper listing over the Ads Transparency actor: search by domain, advertiser name or ID; region, date and format filters; ad details; only-new-ads monitoring; hard stop on CAPTCHA with a free status row when no ads are delivered.

***

*Built and maintained by **ActorForge**. Reliability first: every actor in the
portfolio is monitored by an automated nightly self-test, and breakages are
typically fixed the same day.*

# Actor input Schema

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

Competitor websites, e.g. nike.com. Returns the ads Google lists for that domain in the Ads Transparency Center (Search, YouTube, Display and Shopping), from the brand itself and from agencies or resellers advertising it.

## `advertiserNames` (type: `array`):

Company names as shown in the Ads Transparency Center, e.g. HubSpot, Argos Limited. Exact name matches are used (a brand's several legal entities are all kept); otherwise the closest advertiser with the most ads.

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

Google advertiser IDs (AR… from an adstransparency.google.com/advertiser/AR… link).

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

Only ads shown in these countries, as two-letter codes (US, GB, DE, FR…). Empty = anywhere.

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

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

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

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

## `formats` (type: `array`):

Only these formats. Empty = all formats (text covers Search ads; image and video cover Display, YouTube and Shopping creatives).

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

How many ads to read for each domain, advertiser name or advertiser ID, newest first as the Transparency Center lists them.

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

Stop after this many ads across all searches. You pay per ad delivered ($0.60 per 1,000).

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

One extra lookup per ad: countries shown, impression ranges and first/last shown per country, plus best-effort headline/description text. Charged as ad-detail ($1 per 1,000).

## `onlyNewSinceLastRun` (type: `boolean`):

Remember every ad delivered in a named key-value store (ads-seen-<monitor name>) and return only ads not seen before. Schedule the actor daily to get a feed of competitors' new ads; already-seen ads are skipped and never charged.

## `monitorName` (type: `string`):

Name of the seen-ads memory used by 'Only new ads'. Use one name per schedule (e.g. uk-competitors) so separate watch lists don't share state.

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

Not needed: the Transparency Center is public. Leave off unless you have your own reason to route requests through a proxy. The actor never rotates proxies to get around a block.

## Actor input object example

```json
{
  "domains": [
    "nike.com"
  ],
  "advertiserNames": [],
  "advertiserIds": [],
  "regions": [],
  "formats": [],
  "maxAdsPerAdvertiser": 5,
  "maxResults": 5,
  "includeDetails": false,
  "onlyNewSinceLastRun": false,
  "monitorName": "default",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per ad from the Google Ads Transparency Center.

## `summary` (type: `string`):

Ads delivered, already-seen ads skipped, and whether Google stopped the run early (CAPTCHA / rate limit).

# 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"
    ],
    "maxAdsPerAdvertiser": 5,
    "maxResults": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("actor-forge/google-ads-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"],
    "maxAdsPerAdvertiser": 5,
    "maxResults": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("actor-forge/google-ads-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"
  ],
  "maxAdsPerAdvertiser": 5,
  "maxResults": 5
}' |
apify call actor-forge/google-ads-scraper --silent --output-dataset

```

## MCP server setup

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