# Google Ads Transparency Scraper — Ad Copy & AI Message Summary (`afanasenko/google-ads-transparency-scraper`) Actor

Scrape the Google Ads Transparency Center for any competitor: the ad copy read from each ad (headline, description, call to action), format, first and last shown, still running. Type a brand, website or advertiser ID. Optional AI summary of offers, hooks and CTAs.

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

## Pricing

from $2.00 / 1,000 ads

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 — Ad Copy & AI Message Summary

[![Apify Actor](https://apify.com/actor-badge?actor=afanasenko/google-ads-transparency-scraper)](https://apify.com/afanasenko/google-ads-transparency-scraper)

> **See every ad a competitor runs on Google — with the words of each ad: headline, description, call to action and the website it shows.**
> Type a company name, a website or an advertiser ID. You get one row per ad from the Google Ads Transparency Center — text, image and video ads on Search, YouTube, Shopping, Play, Maps and the display network — with when it was first and last shown and whether it is still running. Turn on the message summary to get each competitor's offers, messages and calls to action, counted across its ads.

> **🆓 Free to start:** 3 advertisers a month on the free plan · the first 25 ads of each advertiser in full · the next 25 shown with their format and dates.

### 🎯 What it does

**You give** one advertiser per line: a company or brand name (`HubSpot`), a website (`hubspot.com`), an advertiser ID (`AR10072600183532683265`) or an advertiser page link from the Ads Transparency Center. A name or a website is matched to the **verified advertiser account(s) behind it**, and only that advertiser's ads are returned — not the ads of agencies or resellers that happen to mention the same site. A company with several accounts under one name (for example three HubSpot accounts) is read as one advertiser.

**You get** one row per ad: the advertiser and its ID, the ad's ID and format, the **headline, description, display URL, call to action and any other words** of the ad, the preview image (or, for a video ad, the video link and thumbnail), when it was first and last shown, how many days it ran, whether it is still running, and its page in the Ads Transparency Center.

**With the message summary on** you also get one summary row per advertiser: its **offers** (free trial, free plan, discount, demo, free resource…), its recurring **messages and claims**, and its **calls to action** — each with how many ads use it, what share of the ads that is, how many of those ads are still running, and example ads in their own words. With several advertisers, the run's status page puts their leading offer, message and call to action side by side.

**Where the words come from.** The ad library does not publish ad text as text — it shows each ad as a rendered preview. This actor reads the words off each text and image ad's preview, exactly as shown, in the ad's own language. A search ad's description is cut with "…" where the preview cuts it.

**What you won't get.** Video ads are not transcribed — you get the video link and thumbnail. The library does not publish impressions, spend or per-country reach, so neither does this actor.

### 📦 Output sample

There are three kinds of rows, told apart by `rowType`:

- **`ad`** — `advertiserName`, `advertiserId`, `verified`, `creativeId`, `format`, `headline`, `description`, `displayUrl`, `callToAction`, `otherText`, `language`, `copyStatus`, `previewImageUrl`, `videoUrl`, `videoThumbnailUrl`, `firstShown`, `lastShown`, `daysActive`, `stillRunning`, `transparencyUrl`, `country`, `platform`, `position`, `rowStatus`, `input`, `note`, `scrapedAt`.
- **`message_summary`** — `advertiserName`, `advertiserId`, `advertiserIds`, `country`, `platform`, `adsAnalysed`, `adsRunning`, `adsWithoutWords`, `summary`, `offers`, `hooks`, `callsToAction`, `input`, `note`, `scrapedAt`.
- **`advertiser_skipped`** — `input`, `skipReason`, `note`, `scrapedAt`: a line no verified advertiser matched, or one the free plan's month left out. Never charged.

An image ad of HubSpot (US, real run of 27.10.2026):

```json
{
  "rowType": "ad",
  "rowStatus": "full",
  "position": 13,
  "advertiserName": "Hubspot, Inc.",
  "advertiserId": "AR10072600183532683265",
  "verified": true,
  "creativeId": "CR08031670009811959809",
  "format": "image",
  "headline": "Your teams, tools, and data — unified",
  "description": "Stop juggling tools. HubSpot unifies your data, teams, and workflows in one place.",
  "displayUrl": "hubspot.com",
  "callToAction": "Learn More",
  "otherText": "Generate quality leads that convert. · Get started",
  "language": "en",
  "copyStatus": "read",
  "previewImageUrl": "https://tpc.googlesyndication.com/archive/simgad/322824003257674309",
  "videoUrl": null,
  "firstShown": "2026-06-17T15:28:10.000Z",
  "lastShown": "2026-10-27T14:39:34.000Z",
  "daysActive": 133,
  "stillRunning": true,
  "transparencyUrl": "https://adstransparency.google.com/advertiser/AR10072600183532683265/creative/CR08031670009811959809?region=US",
  "country": "US",
  "platform": "All platforms",
  "input": "HubSpot"
}
```

A message summary of HubSpot from a run of 30 ads (one item of each list shown; the summary's last sentence trimmed):

```json
{
  "rowType": "message_summary",
  "advertiserName": "Hubspot, Inc.",
  "advertiserIds": ["AR10072600183532683265", "AR13611357312189988865", "AR14972029906777538561"],
  "adsAnalysed": 28,
  "adsRunning": 28,
  "adsWithoutWords": 2,
  "summary": "Hubspot's ads center on free tools (free email tracking, free CRM and marketing software) and on lead generation and AI products such as the AI Notetaker, Agent Builder and AEO. The main calls to action are 'Get started', 'Try it free' and 'Get a demo'.",
  "offers": [
    { "rank": 1, "title": "Free CRM and marketing tools", "kind": "free_plan", "ads": 5, "shareOfAds": 17.9, "stillRunning": 5,
      "examples": [{ "headline": "Free Chatbot Software - HubSpot's Chatbot Software", "description": "Start using HubSpot's chatbot builder for free without any integrations.", "stillRunning": true }] }
  ],
  "hooks": [
    { "rank": 1, "title": "Generate leads and close deals", "ads": 5, "shareOfAds": 17.9, "stillRunning": 5,
      "examples": [{ "headline": "HubSpot Business Software - For Marketing, Sales & Service", "description": "Grow traffic, convert leads, close deals, and turn customers into promoters…", "stillRunning": true }] }
  ],
  "callsToAction": [
    { "rank": 1, "title": "Get started", "ads": 2, "shareOfAds": 7.1, "stillRunning": 2,
      "examples": [{ "headline": "Free Marketing Tools - No CC Required - Get Started Free", "stillRunning": true }] }
  ]
}
```

In Apify Console the dataset has two views:

| View | What it shows |
|---|---|
| **Ads** | advertiser, format, headline, description, call to action, display URL, first and last shown, days active, still running, preview, video, ad page, row status |
| **Message summaries** | advertiser, ads analysed, ads running, summary, offers, messages, calls to action |

### ⚡ Quick start

1. Put `HubSpot` in **Advertisers** (or a competitor's website, like `notion.com`).
2. Leave **Country** on *United States* and **Max ads per advertiser** on 200.
3. Tick **Message summary (AI)** if you want the offers, messages and calls to action summed up.
4. Click **Start**. One advertiser takes about a minute.

### 🧭 When to use it

- **Competitor research** — what your competitors are saying in their Google ads right now: headlines, offers, calls to action, and which ads have run longest.
- **Ad copywriting** — the exact wording that a market's advertisers keep running, as a starting point for your own ads.
- **Agencies and pitches** — a prospect's or a rival's full ad library in one export, with dates, before a meeting.
- **Market monitoring** — run it on a schedule with **Still running only** to see new ads and new offers as they appear.
- **"What are competitors saying?"** — turn on the message summary for several advertisers and compare their leading offer, message and call to action side by side.

### 🛠 Input

| Field | What it does |
|---|---|
| **Advertisers** | One per line: a company or brand name, a website, an advertiser ID (AR…) or an advertiser page link. Up to 25 lines a run. |
| **Country** | Ads shown in this country, or *Anywhere*. The country also decides which advertiser a name is matched to — the one advertising there. |
| **Max ads per advertiser** | Default 200, most recently shown first. Up to 360: 120 of each format (text, image, video). |
| **Message summary (AI)** | One summary row per advertiser: offers, messages and calls to action, counted across up to 300 of its ads with words. |
| **Platform** | All, or only Google Search, YouTube, Google Shopping, Google Play or Google Maps. |
| **Ad format** | All, or only text, image or video ads. |
| **Shown from / Shown to** | Keep the ads shown **at any point** in this window — including ads that started before it and were still running then. |
| **Still running only** | Only the ads shown in the last two days. |

### 💰 How much does it cost to scrape Google Ads Transparency?

You pay per result, and nothing for a lookup that found nothing:

- **Ad** — charged per ad delivered in full, with its words read where the ad has any.
- **Message summary** — charged once per advertiser when its summary is written (only with the message summary on).

Filters are applied before you pay. Ads shown locked on the free plan are not charged. A name that matched no advertiser, and a summary that could not be written, are not charged. The price per event is on the **Pricing** tab.

### 🆓 Free vs paid plan

| | Free plan | Paid plan |
|---|---|---|
| Advertisers a month | 3 | no limit |
| Ads in full per advertiser | 25 | up to 360 |
| Next ads | 25 shown locked (format and dates) | — |
| Message summary | yes, on the ads in full | yes |

### 🧪 Recipes

**Two competitors side by side:** `HubSpot` and `Salesforce`, Message summary on — two summary rows, and the status page compares their leading offer, message and call to action.

**Only search ads:** Platform *Google Search*, Ad format *Text* — headlines and descriptions only.

**What ran during a launch:** Shown from and Shown to around the launch dates — every ad shown at any point in that window.

**What runs now:** Still running only, Message summary on — the offers live today.

**Pin an advertiser exactly:** paste its advertiser ID (`AR10072600183532683265`) or its advertiser page link.

### 📡 Live status & storage records

| Record | What it holds |
|---|---|
| **Live Status** (`status.html`) | Progress while the run works, then what was saved — with several summaries, the side-by-side comparison — or why nothing was. |
| **Run Summary** (`RUN_SUMMARY`) | Per advertiser: how it was matched, the accounts read, ads in the library, fetched, delivered, shown locked and filtered out, how many had their words read, the summary; the comparison; prices and the stop reason. |
| **User Message** (`USER_MESSAGE`) | What happened and what to change — on every run that returned nothing. |
| **Free-Plan Limits Applied** (`FREE_LIMITS_APPLIED`) | The free-plan limits that affected the run. |

### 🤖 Programmatic / API use

```bash
curl -X POST "https://api.apify.com/v2/acts/afanasenko~google-ads-transparency-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"advertisers": ["HubSpot", "notion.com"], "country": "US", "maxAdsPerAdvertiser": 100, "messageSummary": true}'
```

Filter the rows by `rowType`: `ad` for ads, `message_summary` for the summaries. Every column is flat or a short list, so the ads export to CSV and Excel as they are.

### 💡 Tips & Best Practices

#### Getting maximum results

- Type the name as it appears on the company's ads ("HubSpot"), or its main website. If the wrong company comes back, paste the advertiser ID — the Run Summary lists the accounts each line matched.
- An advertiser that runs no ads in your country returns nothing there — try *Anywhere*.

#### Cost optimization

- Set **Max ads per advertiser** to what you will read; 50–100 recent ads already show the main offers.
- Use **Platform**, **Ad format** and the date window instead of filtering afterwards — what does not pass is not charged.

#### Data quality

- The words are copied from each ad's preview as shown — the summary's examples are those same words, never rewritten.
- The summary's counts come from the ads themselves: the AI only groups ads; every number is counted from them.
- `stillRunning` means the ad was shown in the last two days.

### ❓ FAQ

**Where does the ad text come from?**
The Ads Transparency Center shows each ad as a rendered preview. The actor reads the words off each text and image ad's preview — headline, description, display URL, call to action and any other words — exactly as shown. `copyStatus` says, per ad, whether the words were read.

**Why does a video ad have no headline?**
Video ads are not transcribed. Their row links to the video and its thumbnail.

**How is a name or a website matched to an advertiser?**
A name is matched to the verified advertiser account whose name fits it best in the chosen country, together with any other accounts of the same company name. A website is matched through the advertisers showing ads for it, keeping the one whose name carries the brand. The Run Summary says how each line was matched and which accounts were read.

**Does the date window drop ads that started earlier?**
No. An ad is kept if it was shown at any point in the window, whenever it started.

**In what language is the summary?**
English, whatever the language of the ads. The ad copy itself stays in the ad's own language.

**Do I pay for an advertiser that was not found?**
No. Nothing is charged for a line no verified advertiser matched.

### 🔗 Other related actors (same author)

- [App Store & Google Play Reviews Scraper](https://apify.com/afanasenko/app-reviews-scraper) — reviews of any app, with AI complaint and praise themes.
- [Keyword Search Volume](https://apify.com/afanasenko/keyword-search-volume) — monthly search volume and keyword ideas.
- [Backlink Scraper](https://apify.com/afanasenko/backlink-scraper) — backlinks of any website.

### 🛟 Support & feedback

Open the **Issues** tab with the input you used and what you expected. Ideas are welcome there too.

### ⚖️ Is it legal to scrape Google Ads Transparency?

The Ads Transparency Center is a public library of ads and verified advertisers. This actor reads what it shows publicly. Use the data in line with the terms that apply to you, and respect the advertisers' trademarks and copyright when you reuse their ad text or images.

### 📋 Changelog

See the **Changelog** tab.

# Changelog

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

# Actor input Schema

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

One advertiser per line: a company or brand name (HubSpot), a website (hubspot.com), an advertiser ID (AR10072600183532683265) or an advertiser page link from the Ads Transparency Center. A name or a website is matched to the verified advertiser account(s) behind it, and only that advertiser's ads are returned. Up to 25 lines a run.

## `country` (type: `string`):

Ads shown in this country. Anywhere = ads shown in any country. The country also decides which advertiser a name is matched to (the one advertising there).

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

The most ads returned per advertiser line, most recently shown first. Up to 360 — 120 of each format (text, image, video).

## `messageSummary` (type: `boolean`):

Adds one summary row per advertiser: its main offers (free trial, discount, free consultation…), its recurring messages and claims, and its calls to action — each with how many ads use it, how many of those are still running, and example ads in their own words. With several advertisers, the status page puts them side by side. Reads up to 300 ads with words per advertiser. Charged per summary written.

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

Only ads shown on this Google platform.

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

Only ads of this format. Text and image ads get their words read; video ads link to the video.

## `shownFrom` (type: `string`):

Keep the ads shown at any point between this date and "Shown to" — including ads that started earlier and were still running then. Leave both empty for all dates.

## `shownTo` (type: `string`):

The end of the shown-date window (inclusive). Empty = today.

## `stillRunningOnly` (type: `boolean`):

Only the ads shown in the last two days.

## Actor input object example

```json
{
  "country": "US",
  "maxAdsPerAdvertiser": 200,
  "messageSummary": false,
  "platform": "all",
  "format": "all",
  "stillRunningOnly": false
}
```

# Actor output Schema

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

No description

## `messageSummaries` (type: `string`):

No description

## `liveStatus` (type: `string`):

No description

## `userMessage` (type: `string`):

What happened this run and what to change — written on every run that returned no ads, and on free-plan and first-paid runs.

## `runSummary` (type: `string`):

Per advertiser: how it was matched, the accounts read, ads in the library, fetched, delivered, shown locked and filtered out, how many had their words read, the message summary; the side-by-side comparison; prices and the stop reason.

## `freeLimitsApplied` (type: `string`):

Free-plan limits that affected this run. Empty on paid plans.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("afanasenko/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 = {}

# Run the Actor and wait for it to finish
run = client.actor("afanasenko/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 '{}' |
apify call afanasenko/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

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