# Google Ads Analyzer (`amernas/google-ads-analyzer`) Actor

Extract ad data from Google Ads Transparency Center by domain. Three modes: FULL (basic data), OCR (AI text extraction from images - headlines, descriptions, URLs), and LITE (summary counts). Filter by date range and region. Perfect for competitor analysis and ad research.

- **URL**: https://apify.com/amernas/google-ads-analyzer.md
- **Developed by:** [Traffic Architect](https://apify.com/amernas) (community)
- **Categories:** SEO tools, Lead generation, E-commerce
- **Features:** Limited permissions
- **Stats:** 30 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: 1.00 out of 5 stars

## Pricing

$1.00 / 1,000 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 - Extract Ads from Google Ads Transparency Center

Scrape and extract ad data from the [Google Ads Transparency Center](https://adstransparency.google.com/) by domain name. This Google Ads scraper gives you impression stats, targeting info, platform breakdowns, advertiser details, and optionally extracts ad copy text via OCR - perfect for competitor ad analysis, ad spy research, and market intelligence.

### What data does this Google Ads extractor return?

- **Impression ranges** (min/max) per region and per platform
- **Platform breakdown** - Google Search, YouTube, Maps, Shopping, Display
- **Targeting info** - demographics, locations, contextual signals, customer lists, topics of interest
- **Advertiser details** - legal name, region code, verification info
- **Ad metadata** - format (TEXT/IMAGE/VIDEO), topic category, first/last shown dates
- **Ad copy text** (OCR mode) - extract headlines, descriptions, and CTAs from ad creative images

> **Don't need OCR?** [amernas/google-ads-transparency-analyzer](https://apify.com/amernas/google-ads-transparency-analyzer) provides the same data without OCR, using a lighter Docker image.

### Input

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `keywords` | string | Yes | - | Domain name (e.g. `clay.com`) or full Google Ads Transparency URL |
| `runMode` | string | No | `FULL` | `FULL` for detailed ads, `OCR` for ads + text extraction, `LITE` for format counts only |
| `dateRangePreset` | string | No | `ANYTIME` | `ANYTIME`, `LAST_7_DAYS`, `LAST_30_DAYS`, or `CUSTOM_RANGE` |
| `customStartDate` | string | No | - | Start date `YYYY-MM-DD` (only with `CUSTOM_RANGE`) |
| `customEndDate` | string | No | - | End date `YYYY-MM-DD` (only with `CUSTOM_RANGE`) |
| `count` | integer | No | `10` | Max number of ad creatives to retrieve |
| `region` | string | No | `anywhere` | Region code to filter by (e.g. `US`, `GB`, `DE`) |
| `proxyConfig` | object | No | Apify Proxy | Proxy configuration |

#### Example input

```json
{
  "keywords": "clay.com",
  "runMode": "FULL",
  "dateRangePreset": "LAST_30_DAYS",
  "count": 10,
  "region": "US"
}
```

### Output

#### FULL mode - ad details with impression data

Each item in the dataset represents one ad creative with full stats:

```json
{
  "url": "https://adstransparency.google.com/advertiser/AR04896.../creative/CR03301...?region=anywhere",
  "advertiserId": "AR04896179704312102913",
  "creativeId": "CR03301252824532254721",
  "type": "VIDEO",
  "lastShown": "2026-04-02T19:36:54.000Z",
  "topic": 10005,
  "targeting": {
    "demographics": { "including": true, "excluding": false },
    "locations": { "including": true, "excluding": false },
    "contextualSignals": { "including": true, "excluding": true },
    "customerLists": { "including": true, "excluding": false },
    "topicsOfInterest": { "including": true, "excluding": false }
  },
  "stats": {
    "byRegion": [
      {
        "name": "Greece",
        "shortCode": "GR",
        "firstShown": "2024-06-15",
        "lastShown": "2026-04-02",
        "impression": { "min": 350000, "max": 400000 },
        "byPlatform": [
          { "name": "Youtube", "impression": { "min": 350000, "max": 400000 } }
        ]
      }
    ],
    "byPlatform": [
      { "name": "Youtube", "impression": { "min": 350000, "max": 400000 } }
    ]
  },
  "advertiser": {
    "id": "AR04896179704312102913",
    "name": "Michalakou Panagiota-Nikoletta",
    "regionCode": "GR",
    "legalName": "Michalakou Panagiota-Nikoletta"
  },
  "variants": [],
  "originalKeyword": "pharm16.gr"
}
```

#### OCR mode - ad copy text extraction

Same as FULL mode, with an additional `ocrData` field containing extracted ad copy:

```json
{
  "ocrData": {
    "rawText": "Sponsored\nclay.com\nAutomate Inbound\nScore and route leads automatically.",
    "ocrError": null
  }
}
```

#### LITE mode - quick ad format counts

Returns format counts per domain without fetching individual ad details:

```json
{
  "originalKeyword": "clay.com",
  "keyword": "clay.com",
  "advertisersFound": { "AR123...": "Clay Inc." },
  "textCreativeCount": 15,
  "imageCreativeCount": 8,
  "videoCreativeCount": 3,
  "unknownFormatCount": 0,
  "regionSearched": "US",
  "totalCreativesCountedFromSearch": 26
}
```

### Use cases

- **Competitor ad spy** - see what ads competitors are running, where, and how many impressions they get
- **Ad copy research** - extract headlines, descriptions, and CTAs from ad creatives using OCR mode
- **Google Ads market research** - discover which platforms and regions a brand focuses on
- **Ad monitoring and tracking** - track when ads appear and disappear across regions
- **Advertiser compliance audit** - verify advertiser identity, legal name, and targeting practices

### FAQ

#### How do I scrape Google Ads for a competitor's domain?

Set the `keywords` field to the competitor's domain (e.g. `competitor.com`). The scraper searches the Google Ads Transparency Center and returns all active ad creatives, impression counts, and targeting details for that domain.

#### What is the Google Ads Transparency Center?

The [Google Ads Transparency Center](https://adstransparency.google.com/) is Google's public database of all ads running across Google Search, YouTube, Maps, Shopping, and Display. Anyone can look up ads by advertiser or domain. This scraper automates that lookup and extracts structured data.

#### Can I get exact impression counts?

Google reports impressions as ranges (e.g. 350,000-400,000), not exact numbers. This is how the Transparency Center works - the scraper returns the min/max range as reported by Google.

#### Can I extract ad copy text (headlines, descriptions, CTAs)?

Yes - use `runMode: "OCR"`. The scraper captures ad creative preview images and runs OCR to extract visible text. Accuracy depends on image quality. For text ads, Google serves JavaScript-rendered previews that don't always produce clean OCR output.

#### What platforms are covered?

Google Search, YouTube, Google Maps, Google Shopping, and Google Display Network. The scraper returns impression breakdowns per platform for each ad creative.

#### Can I filter ads by country or region?

Yes - set the `region` field to a country code like `US`, `GB`, `DE`, `FR`, etc. Use `anywhere` (default) to see ads across all regions.

#### How is this different from google-ads-transparency-analyzer?

This actor (`google-ads-analyzer`) includes OCR-based ad copy extraction. If you don't need ad text, use [amernas/google-ads-transparency-analyzer](https://apify.com/amernas/google-ads-transparency-analyzer) - it's a lighter image with the same data minus OCR.

#### Can I scrape ads for multiple domains?

Currently the actor accepts one domain per run. To scrape multiple domains, trigger separate runs or use the Apify API to orchestrate batch runs.

### Limitations

- **Ad copy text** is extracted via OCR from preview images, so accuracy depends on image quality. Not all creatives have extractable preview images.
- **Video URLs** are not directly exposed by the Google Ads Transparency Center.
- Impression data is provided as ranges (min/max), not exact numbers - this is how Google reports it.

### Feedback

If you have any issues or feature requests, please reach out through the Apify console.

# Actor input Schema

## `keywords` (type: `string`):

A single domain name (e.g., 'clay.com', 'apify.com') or Google Ads Transparency Center URL (e.g., 'https://adstransparency.google.com/?region=anywhere\&domain=clay.com') to search for ads.

## `runMode` (type: `string`):

Select the run mode. 'FULL' fetches detailed ad information without OCR. 'OCR' fetches detailed ad information WITH OCR text extraction. 'LITE' fetches only counts of ad creatives per format for each advertiser.

## `dateRangePreset` (type: `string`):

Select a preset date range for filtering ads, or choose 'Custom Range' to specify start and end dates.

## `customStartDate` (type: `string`):

Specify the start date for the custom date range (e.g., 2023-01-01). Used only if 'Date Range Preset' is 'Custom Range'.

## `customEndDate` (type: `string`):

Specify the end date for the custom date range (e.g., 2023-01-31). Used only if 'Date Range Preset' is 'Custom Range'.

## `count` (type: `integer`):

The maximum number of ad creatives to retrieve for each keyword/found advertiser when in FULL or OCR mode. For LITE mode, the actor attempts to count all relevant creatives.

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

The region code to filter ads by (e.g., 'US', 'GB'). Use 'anywhere' for no specific region. Refer to README.md or script's show_regions_list() for available codes.

## `proxyConfig` (type: `object`):

Select proxies to be used by the scraper. Uses Apify Proxy or custom proxy URLs.

## Actor input object example

```json
{
  "runMode": "FULL",
  "dateRangePreset": "ANYTIME",
  "count": 10,
  "region": "anywhere",
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": []
  }
}
```

# Actor output Schema

## `resultDataset` (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 = {
    "proxyConfig": {
        "useApifyProxy": true,
        "apifyProxyGroups": []
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("amernas/google-ads-analyzer").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 = { "proxyConfig": {
        "useApifyProxy": True,
        "apifyProxyGroups": [],
    } }

# Run the Actor and wait for it to finish
run = client.actor("amernas/google-ads-analyzer").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 '{
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": []
  }
}' |
apify call amernas/google-ads-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,amernas/google-ads-analyzer"
        }
    }
}
```

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/NboSzwqSgUSFck0So/builds/70kPRFPOxuNQmcqRF/openapi.json
