# Google Ads Transparency Scraper with Ad Copy (`kilometric_camp/google-ads-transparency-ad-copy`) Actor

Scrape Google Ads Transparency Center with the real ad copy: Search ad headlines & descriptions, landing pages with UTM tags, video files, YouTube IDs and Shopping products.

- **URL**: https://apify.com/kilometric_camp/google-ads-transparency-ad-copy.md
- **Developed by:** [Çınar Özkan](https://apify.com/kilometric_camp) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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 Transparency Scraper with Ad Copy

See what any brand's Google ads **actually say**, **where they lead** and **how long they have run**. Search by domain, brand name or advertiser ID - no login, no browser, no API key.

**Try it in about a minute:** keep the default input (`nike.com`) and press **Start**. You get 20 ads with headline, description, display URL and dates for about 8 cents.

### What you get in every ad record

- **Search ad copy** - headline, description and display URL of Google Search text ads. Google stores these ads as pictures, so the copy is read out of the image.
- **Landing pages and UTM tags** of video ads, including the campaign name (`utm_campaign`).
- **Video files** - direct MP4 links, duration and the YouTube video ID.
- **Shopping ads** - product title, merchant and product image.
- **The context** - advertiser name and ID, ad format, first and last shown dates, days shown, every variation of the ad, per-country details and a link to the ad in the Transparency Center.

Results stream into the dataset while the Actor runs, so you can export partial runs as JSON, CSV or Excel at any time.

### What can I do with it?

- **Study competitor ad copy** - build a swipe file of the headlines and descriptions a brand has run for months. `daysShown` shows which ads stayed live the longest.
- **Monitor new ads** - schedule a daily run and spot new creatives by `firstShown`.
- **Reverse-engineer campaigns** - landing pages and `utm_campaign` names of video ads show how a brand structures its campaigns.
- **Win pitches** - show a prospect exactly which ads they run and for how long.
- **Research creatives** - collect videos, images and Shopping ads by brand, format, platform and country.

### How it works

1. Add one or more **domains** (`nike.com`), **brand names** (`HubSpot`) or **advertiser IDs** (`AR16735076323512287233`).
2. Optionally narrow it down by country, platform (Search, YouTube, Shopping, Maps, Play), ad format and date range.
3. Press **Start**. Download the dataset as JSON, CSV or Excel, or read it through the Apify API.

### Input

| Field | What it does |
|---|---|
| **Domains, brand names or advertiser IDs** (`queries`) | One per line: `nike.com`, `HubSpot`, `AR16735076323512287233`, or an advertiser URL from the Transparency Center. A brand name is matched to the best advertisers automatically. |
| **Country** (`region`) | 2-letter code (`US`, `GB`, `DE`, `TR` ...) or `ANYWHERE`. |
| **Platform** (`platform`) | Google Search, YouTube, Google Shopping, Google Maps or Google Play. |
| **Ad format** (`adFormat`) | Text, image or video. |
| **Shown in the last N days** (`lastDays`) or **Start / End date** | Ads that were shown during that period. Google keeps about 12 months of history. |
| **Max ads per advertiser / domain** (`maxAdsPerQuery`) | Default 20 for a quick first run. Raise it for full exports. |
| **Include creative details** (`includeDetails`) | Loads every variation of each ad: landing page and UTM tags, video files, YouTube IDs, Shopping product titles, per-country dates. |
| **Extract Search ad copy** (`extractAdText`) | Reads headline and description out of Search text ads. |
| **Proxy** (`proxyConfiguration`) | Apify Proxy is on by default. |

Example input:

```json
{
  "queries": ["nike.com", "HubSpot"],
  "region": "US",
  "lastDays": 30,
  "maxAdsPerQuery": 100,
  "includeDetails": true,
  "extractAdText": true
}
```

### Output

Search text ad:

```json
{
  "advertiserId": "AR16735076323512287233",
  "advertiserName": "Nike, Inc.",
  "creativeId": "CR11238584882709921793",
  "format": "TEXT",
  "firstShown": "2023-11-16",
  "lastShown": "2026-10-22",
  "daysShown": 1072,
  "domain": "nike.com",
  "headline": "Nike Official Site - The Latest Nike® Football Gear",
  "description": "Designed and created to enable outstanding performance, Nike football gear. The latest innovations that allow you to bring out your best game. Gear up at Nike®. Live Support Available.",
  "displayUrl": "www.nike.com/shop/football",
  "adTextSource": "ocr",
  "adUrl": "https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR11238584882709921793?region=US"
}
```

Video ad:

```json
{
  "advertiserId": "AR13611357312189988865",
  "advertiserName": "HubSpot",
  "creativeId": "CR12217674844505899009",
  "format": "VIDEO",
  "firstShown": "2026-10-09",
  "lastShown": "2026-10-22",
  "daysShown": 14,
  "landingUrl": "https://www.hubspot.com?utm_source=OTT-CTV_DV360-Multi&utm_medium=paid_brandstrategy&utm_campaign=BrandStrategy_VideoViews_...",
  "utm": {
    "utm_source": "OTT-CTV_DV360-Multi",
    "utm_medium": "paid_brandstrategy",
    "utm_campaign": "BrandStrategy_VideoViews_EN_NAM_NAM_GBC_OTT_Multi_AnnoyinglyGood-Q4-2026_..."
  },
  "videoDuration": "00:00:30",
  "videoFileUrls": ["https://gcdn.2mdn.net/videoplayback?id=9caba06735ba3043&itag=22&source=web_video_ads..."],
  "adUrl": "https://adstransparency.google.com/advertiser/AR13611357312189988865/creative/CR12217674844505899009?region=US"
}
```

| Field | Description |
|---|---|
| `advertiserId`, `advertiserName`, `creativeId` | Identify the advertiser and the ad. |
| `format` | `TEXT`, `IMAGE` or `VIDEO`. |
| `firstShown`, `lastShown`, `daysShown` | When Google first and last showed the ad. |
| `domain` | Advertiser domain, when known. |
| `headline`, `description`, `displayUrl` | Search text ad copy. `adTextSource` is `ocr` (read from the archived ad image) or `preview` (from Google's ad preview). `adText.confidence` (0-1) tells how sure the text reading is. |
| `landingUrl`, `utm` | Where the ad leads and its `utm_*` tags (video ads). |
| `videoFileUrls`, `videoDuration` | Direct MP4 links and length (video ads). The links are signed and expire - download them soon. |
| `youtubeVideoIds`, `youtubeUrls` | YouTube video, when the ad is a YouTube video. |
| `productTitle`, `merchant` | Shopping ads. |
| `imageUrl`, `imageUrls` | Ad images. |
| `adUrl` | The ad on the Transparency Center. |
| `variations`, `regionStats` | Full detail objects (when **Include creative details** is on). |

### Pricing

Pay per event - you only pay for what you turn on:

| Event | Price | Charged when |
|---|---|---|
| Ad result (dataset item) | **$1.00 / 1,000** | an ad is saved to the dataset |
| Ad details | **$1.00 / 1,000** | the creative details of an ad were loaded |
| Ad text | **$2.00 / 1,000** | the headline and description of a Search text ad were read |

Examples: a plain list of 1,000 ads (details and ad text off) costs **$1.00**. 1,000 ads with details, where 500 are Search text ads: 1,000 x $0.001 + 1,000 x $0.001 + 500 x $0.002 = **$3.00**. The default run (20 ads, most of them Search text ads) costs about **$0.08**.

Apify platform usage is included in these prices - you pay only for the events above, and nothing for starting a run.

Set a **maximum cost per run** in the run options - the Actor stops when it is reached.

### Use it from your code

```python
## pip install "apify-client>=3"
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("kilometric_camp/google-ads-transparency-ad-copy").call(
    run_input={"queries": ["nike.com"], "maxAdsPerQuery": 50}
)
for ad in client.dataset(run.default_dataset_id).iterate_items():
    print(ad["format"], "|", ad.get("headline"), "|", ad.get("landingUrl"))
```

The same works from JavaScript, the Apify CLI or any HTTP client - see the **API** tab.

### Integrations

Send results to Google Sheets, Slack, Make, Zapier, n8n or your own webhook with Apify integrations, and run the Actor on a schedule.

### Good to know

- **12 months of history.** Google's date filter reaches back about a year. Older periods return nothing. The `firstShown` date of an ad can be older.
- **Ad text is read from an image.** Google stores Search text ads as pictures, so the copy is read with OCR. It works best on English; accented letters and symbols (for example `é`, `¡`, `®`) can be replaced or dropped, and non-Latin scripts are not supported. Check `adText.confidence`.
- **No impressions, reach or spend.** This Actor does not return those numbers.
- **Speed.** In my tests on the Apify platform, a plain list of 2,000 ads took about 1 minute, and 200 ads with creative details took about 75 seconds. Reading Search ad copy is the slow part: expect roughly 15-20 text ads per minute.
- **Big exports.** Large advertisers have thousands of ads. For a complete export, split the job by country, platform, format or date range.
- **Rate limits.** If Google rate-limits a run, the Actor slows down and rotates the proxy IP automatically. If you still see rate-limit warnings in the log on large runs, switch the proxy group to **Residential** in the Proxy input.
- **Memory.** Peak memory in my test was about 300 MB, but reading Search ad copy is CPU-heavy and Apify gives one CPU core per 4096 MB. Use 2048-4096 MB when extracting ad text; for plain lists, less is fine.

### FAQ

**How do I see my competitors' Google ads?** Enter their domain or brand name. The Actor returns the ads Google lists for that advertiser in the Transparency Center, with the copy and landing pages where Google exposes them.

**Can I get the landing page of Search text ads?** No. For Search text ads Google shows only the display URL. Landing pages and UTM tags are available for video ads.

**Can I export to CSV, Excel or Google Sheets?** Yes. Export the dataset in any format from the Apify Console, or connect Google Sheets with an Apify integration.

**Is this affiliated with Google?** No. This Actor is independent. "Google" and "Google Ads" are trademarks of Google LLC. It reads the public pages of the Ads Transparency Center.

**Is it legal to scrape the Ads Transparency Center?** The Actor reads the public pages of Google's Ads Transparency Center without logging in. You are responsible for how you use the data and for following Google's terms and the laws that apply to you (for example GDPR if you process data about individuals). This is not legal advice.

**Can I run it on a schedule or send results to other tools?** Yes. Use Apify schedules, webhooks and integrations (Google Sheets, Slack, Make, Zapier, the API) like with any Actor.

**Something is missing or wrong?** Open an issue in the **Issues** tab with the input you used - bug reports and field requests are welcome.

# Actor input Schema

## `queries` (type: `array`):

One per line. Examples: nike.com, HubSpot, AR16735076323512287233, or a Transparency Center advertiser URL. Brand names are matched to advertisers automatically.

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

2-letter country code where the ads were shown (US, GB, DE, FR, TR ...). Use ANYWHERE for all countries.

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

Only ads shown on this Google platform. Platform data exists for ads shown after 2023-09-04.

## `adFormat` (type: `string`):

Only ads in this format (text, image or video). ALL returns every format.

## `lastDays` (type: `integer`):

Only ads that were shown during the last N days (1-365). Google keeps about 12 months of history. Leave empty to use Start/End date instead, or no date filter.

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

YYYY-MM-DD. Ads shown on or after this date. Google keeps about 12 months of history; earlier dates return nothing.

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

YYYY-MM-DD. Ads shown on or before this date.

## `maxAdsPerQuery` (type: `integer`):

How many ads to collect for each domain or advertiser. Default 20 for a quick first run; raise it for full exports (up to 50,000). Reading the copy of Search text ads takes about 3-4 seconds per ad (roughly 15-20 ads per minute), so use 2048 MB memory or more for big runs.

## `maxAdvertisersPerQuery` (type: `integer`):

When a query is a brand name, how many matching advertisers to include.

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

Fetch every variation of each ad: YouTube video IDs, image URLs, Shopping product titles, per-country dates. Charged as 'ad-details'.

## `extractAdText` (type: `boolean`):

Google stores Search text ads as images. This reads the copy out of them (headline, description, display URL, extensions). Charged as 'ad-text' only when text is found.

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

Google rate-limits heavy use. Apify Proxy rotates IPs automatically when that happens.

## Actor input object example

```json
{
  "queries": [
    "nike.com"
  ],
  "region": "US",
  "platform": "ALL",
  "adFormat": "ALL",
  "maxAdsPerQuery": 20,
  "maxAdvertisersPerQuery": 3,
  "includeDetails": true,
  "extractAdText": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `ads` (type: `string`):

The ads as a table: advertiser, format, headline, description, display URL, dates and a link to each ad. Export as JSON, CSV or Excel.

## `allFields` (type: `string`):

Every field of every ad, including landing pages with UTM tags, video file links, YouTube IDs, ad variations and per-country dates.

# 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 = {
    "queries": [
        "nike.com"
    ],
    "maxAdsPerQuery": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("kilometric_camp/google-ads-transparency-ad-copy").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 = {
    "queries": ["nike.com"],
    "maxAdsPerQuery": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("kilometric_camp/google-ads-transparency-ad-copy").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 '{
  "queries": [
    "nike.com"
  ],
  "maxAdsPerQuery": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call kilometric_camp/google-ads-transparency-ad-copy --silent --output-dataset

```

## MCP server setup

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

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/jIeTK4qpFPcfJFJH4/builds/76ovvaOElWu8Brkc7/openapi.json
