# Google Ads Transparency Scraper – Ad Copy, Countries & Reach (`smoldesk/google-ads-transparency-scraper`) Actor

Scrape the Google Ads Transparency Center: every ad a competitor runs on Search, YouTube, Shopping, Maps & Play with headline, text, landing page, images, countries, EU impressions, audience & political spend. No login, no start fee.

- **URL**: https://apify.com/smoldesk/google-ads-transparency-scraper.md
- **Developed by:** [Smoldesk Studios](https://apify.com/smoldesk) (community)
- **Categories:** Lead generation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.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 – Creatives, Countries & Reach

Scrape the **Google Ads Transparency Center** and see **every ad a competitor runs on Google Search, YouTube, Shopping, Maps and Play**. Search by **domain** (`nike.com`), **advertiser name** or **advertiser ID**, filter by **country, format, platform and date**, and get one row per ad with the **ad image or YouTube video**, **first and last shown dates**, and the **headline, description, call to action and landing page** wherever Google keeps the ad as text (most video and display ads; Search ads usually come as an image of the full ad — see Limitations). Turn on full details for **every country the ad ran in**, **impression ranges per country and per Google platform** (EU and political ads), the **audience selection** (demographics, locations, contextual signals, customer lists, interests), **Google's topic label** and the advertiser's **legal name and country**. **Political ads** come with **spend and impression ranges**. A **monitoring mode** returns only ads that are new since your last run. No login, no API key, no browser, no start fee.

### What you can use it for

- **Competitor ad research**: pull every live creative of a rival brand, see what they say, where they send traffic and how long each ad has been running.
- **Creative inspiration and swipe files**: collect long-running ads (high `daysShown`) — the ones that work are the ones advertisers keep paying for.
- **New-ad alerts**: schedule a daily run with **Only new ads** and get just the creatives a competitor launched since yesterday.
- **Agency pitches and audits**: show a prospect which competitors advertise in their market, on which Google products, in which countries.
- **EU reach analysis**: impression ranges per country and per platform, and the audience criteria advertisers chose (Digital Services Act data).
- **Election and political ad monitoring**: spend ranges, impressions and the regions each political ad targeted.
- **Brand protection**: search your own domain to find resellers, affiliates and look-alike advertisers bidding on your traffic.
- **AI agents and RAG**: every ad has a clean `markdown` summary ready for an LLM.

### How to scrape Google Ads Transparency

1. Create a free Apify account and open this Actor.
2. Say whose ads you want:
   - **Domains**: `nike.com`, `booking.com` — every advertiser sending traffic there (brand, resellers, agencies).
   - **Advertisers**: a name like `Shopify`, an advertiser ID (`AR16735076323512287233`) or the advertiser's page URL. Google lists advertisers under legal names, so a name goes to the biggest account carrying it (`Shopify` → Shopify Inc.); if no big account has the name (`Temu`, `Canva`), the Actor searches the brand's domain instead and says so in the log.
   - **Ads Transparency Center URLs**: paste any URL from adstransparency.google.com — its filters are kept. A single ad URL returns that ad with full details.
   - **Political ads only**: the latest election ads in the chosen countries, with spend.
3. Narrow it down with **Countries** (`US`, `GB`, `DE`…), **Ad format** (text, image, video), **Google platform** (Search, YouTube, Shopping, Maps, Play) and **Shown on or after / before** dates (`2026-09-01`, `-30`).
4. Leave **Ad copy** on for headline, text, call to action and landing page. Turn on **Full details** for countries, impressions, audience and all variations.
5. Click **Start**. 100 ads take a few seconds; with full details about 1 minute.
6. Download as JSON, CSV or Excel, or read the dataset through the Apify API.
7. For alerts, turn on **Only new ads** and add a **Schedule** (daily or weekly). Each run returns only creatives first shown since the previous run.

**Tips**

- Start without full details to see how many ads a brand runs (`Google lists about …` in the log), then add details for the ads you care about.
- Big brands run tens of thousands of ads — use **Max ads per domain / advertiser**, a country and a date filter.
- Some brands have one advertiser account per country. Turn on **All advertisers with that name** to get them all.

### Output: ad

```json
{
  "type": "ad",
  "advertiserId": "AR06374349942554624001",
  "advertiserName": "Canva, Pty Ltd",
  "creativeId": "CR15674834518026485761",
  "adUrl": "https://adstransparency.google.com/advertiser/AR06374349942554624001/creative/CR15674834518026485761?region=US",
  "format": "video",
  "firstShown": "2026-09-07T04:32:06Z",
  "lastShown": "2026-10-18T14:38:18Z",
  "daysShown": 43,
  "domain": "canva.com",
  "headline": "Start designing with Canva today",
  "longHeadline": "Save hours designing your social posts with Canva’s free templates.",
  "description": "Sign up to Canva and choose from millions of free templates.",
  "callToAction": "Learn more",
  "businessName": "Canva",
  "displayUrl": null,
  "landingUrl": null,
  "youtubeVideoId": "KoSaMtJK_gM",
  "youtubeUrl": "https://www.youtube.com/watch?v=KoSaMtJK_gM",
  "videoDuration": "0:18",
  "appId": null,
  "imageUrl": "https://i.ytimg.com/vi/KoSaMtJK_gM/hqdefault.jpg",
  "imageUrls": ["https://i.ytimg.com/vi/KoSaMtJK_gM/hqdefault.jpg"],
  "productTitle": null,
  "productMerchant": null,
  "dynamicSearchAd": false,
  "searchRegions": ["US"],
  "searchQuery": "canva.com",
  "markdown": "**Canva, Pty Ltd** — video ad for canva.com\nHeadline: Start designing with Canva today\n…",
  "scrapedAt": "2026-10-18T15:22:09+00:00"
}
```

With **Full details** on, each ad also has:

```json
{
  "topic": "Travel & Tourism",
  "adType": "Commercial",
  "regionCount": 7,
  "regions": [
    {
      "country": "NL",
      "countryName": "Netherlands",
      "firstShown": "2025-10-24",
      "lastShown": "2026-10-18",
      "impressionsMin": 20000,
      "impressionsMax": 25000,
      "platforms": [
        {"platform": "Google Search", "impressionsMin": 20000, "impressionsMax": 25000},
        {"platform": "Google Shopping", "impressionsMin": 0, "impressionsMax": 1000}
      ]
    }
  ],
  "euImpressions": {"impressionsMin": 25000, "impressionsMax": 30000, "firstShown": "2025-10-24", "lastShown": "2026-10-18"},
  "audienceSelection": {
    "demographicInfo": "included",
    "geographicLocations": "included and excluded",
    "contextualSignals": "included"
  },
  "variationCount": 3,
  "variations": [{"headline": "…", "description": "…", "imageUrls": ["…"]}],
  "advertiserLegalName": "Booking.com B.V.",
  "advertiserCountry": "NL",
  "advertiserCountryName": "Netherlands",
  "advertiserVerified": true
}
```

Political ads add:

```json
{
  "political": {
    "impressionsMin": 35000,
    "impressionsMax": 40000,
    "spendCurrency": "USD",
    "spendMin": 500,
    "spendMax": 600,
    "regions": ["US"]
  }
}
```

### Input examples

Competitor ads in the US, newest 200, with ad copy:

```json
{
  "domains": ["booking.com", "expedia.com"],
  "regions": ["US"],
  "maxAdsPerSearch": 200
}
```

A brand's YouTube video ads in Germany since September, with countries, impressions and audience:

```json
{
  "advertisers": ["AR16735076323512287233"],
  "regions": ["DE"],
  "adFormat": "VIDEO",
  "platform": "YOUTUBE",
  "startDate": "2026-09-01",
  "includeDetails": true
}
```

Daily new-ad alerts (schedule this):

```json
{
  "domains": ["competitor.com"],
  "regions": ["GB"],
  "onlyNewAds": true
}
```

Political ads in the US with spend:

```json
{
  "politicalAdsOnly": true,
  "regions": ["US"],
  "maxAdsPerSearch": 500
}
```

### Pricing

Pay only for the ads you get. No monthly rent, a near-zero start fee.

| What | Price |
|---|---|
| Ad (with ad copy, image, landing page, dates) | **$1.00 per 1,000 ads** |
| Full details add-on (countries, impressions, audience, topic, variations, advertiser info) | **+$2.00 per 1,000 ads** |
| Actor start | $0.00005 per run |

Examples: 1,000 competitor ads with ad copy = **$1.00**. 1,000 ads with full details = **$3.00**. A daily new-ads check that finds 15 new creatives costs **$0.015**. Ads that were skipped (already seen, outside your filters) are never charged. Set **Maximum cost per run** in the run options and the Actor stops cleanly when it is reached.

### Use with AI (LangChain / LlamaIndex / CrewAI)

Each ad has a `markdown` field (advertiser, headline, text, call to action, landing page, dates, countries), so the dataset drops straight into an LLM or vector store:

```python
from langchain_apify import ApifyDatasetLoader
from langchain_core.documents import Document

loader = ApifyDatasetLoader(
    dataset_id="<your run's dataset ID>",
    dataset_mapping_function=lambda ad: Document(
        page_content=ad["markdown"],
        metadata={"advertiser": ad["advertiserName"], "url": ad["adUrl"], "format": ad["format"]},
    ),
)
docs = loader.load()
```

Ask your agent "What messages does this competitor test on YouTube?" or "Which landing pages get the most ads?". The Actor also works as a tool in the Apify MCP server (`smoldesk/google-ads-transparency-scraper`).

### Limitations

- **Ad copy depends on what Google stores.** In our tests (500 US ads, 5 brands) the text fields were filled for **~80% of video ads** and **~40% of image/display ads** (the rest are HTML5 banners with no readable text). **Search text ads are mostly stored by Google as a screenshot**: you get that image in `imageUrl` (it shows the full ad — headline, URL and text) but the text fields stay empty for ~95% of them. With **Full details** on, the Actor reads every variation (up to 5) and fills the text from the first one Google keeps as text, which works for some advertisers (e.g. most Nike Search ads) and not others.
- **Impressions and audience** are published by Google only for ads shown in the **EU** (and for political ads). For other countries you get first/last shown dates per country; impressions are `null`.
- **Dynamic Search Ads** have no fixed headline: `dynamicSearchAd` is `true` and `headline` is `null`.
- Google's ad count per search is approximate (shown as a range in the log).
- HTML5 banner ads have no readable text; you get their size and the ad page link.
- The Center lists ads from verified advertisers, back to about 2020.

### FAQ

**Is there a Google Ads Transparency Center API?**
No public one. This Actor reads the same data the Ads Transparency Center website shows and returns it as structured JSON — effectively a Google Ads Transparency API without an API key.

**Is it legal to scrape the Ads Transparency Center?**
The Center is a public website Google built so anyone can see who is advertising and what. The Actor reads only that public information, without logging in. Check your local laws and the terms of the sites you work with before using the data.

**Do I need a Google account or a proxy?**
No. The Actor needs no login. It sends requests from its own IP and switches IP by itself when Google slows it down — you don't configure anything.

**How do I find all ads of a competitor?**
Search by their domain to get every advertiser sending traffic there, or by advertiser name to get only their own account. Add **All advertisers with that name** for brands with one account per country.

**How do I get alerts for new ads?**
Turn on **Only new ads** and schedule the Actor. The first run returns the current ads; each later run returns only ads first shown after the previous run.

**Can I get the ad images and videos?**
Yes — `imageUrl` / `imageUrls` link to the ad image (for many text ads, a screenshot of the full ad), and video ads have `youtubeVideoId` and `youtubeUrl`.

**Does it scrape the Meta (Facebook) Ad Library?**
No, Google only. It covers Google Search, YouTube, Shopping, Maps, Play and the Display Network.

### Feedback

Missing a field, or an ad that doesn't look right? Open an issue on the Issues tab — fixes usually ship within a day.

### More Actors from Smoldesk Studios

- [Tennis Scraper](https://apify.com/smoldesk/tennis-scraper): results, fixtures, closing and opening odds from 15 bookmakers, H2H and ATP/WTA rankings
- [Weibo Scraper](https://apify.com/smoldesk/weibo-scraper): keyword and hashtag search, posts, comments, profiles and the hot-search board from China's biggest microblog, no login
- [Bilibili Scraper](https://apify.com/smoldesk/bilibili-scraper): videos, stats, danmaku, comments and creators from China's video site, no login
- [Google Hotels Scraper](https://apify.com/smoldesk/google-hotels-scraper): hotel prices for your dates in any currency, ratings, review aspects and booking-site prices, worldwide
- [Google Trends Scraper](https://apify.com/smoldesk/google-trends-scraper): interest over time, by region and city, related queries and Trending now — no API key
- [Telegram Channel Scraper](https://apify.com/smoldesk/telegram-channel-scraper): public channel posts, views, reactions and subscribers
- [Substack Scraper](https://apify.com/smoldesk/substack-scraper): newsletters, subscriber counts and posts
- [Shopify Store Analyzer](https://apify.com/smoldesk/shopify-store-analyzer): apps, contacts and products of any Shopify store
- [Career Site Jobs Scraper](https://apify.com/smoldesk/career-site-jobs-scraper): live jobs from 13,000+ company career sites (Greenhouse, Lever, Workday, Ashby) with salary and seniority
- [SEEK, JobStreet & JobsDB Scraper](https://apify.com/smoldesk/seek-jobs-scraper): jobs and salaries across Australia and Southeast Asia

# Actor input Schema

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

Websites whose ads you want, e.g. nike.com or booking.com. Google returns every advertiser that sends traffic to the domain (the brand itself plus resellers and affiliates).

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

Advertiser names (e.g. Shopify), advertiser IDs (AR…) or advertiser page URLs. Google lists advertisers under their legal names, so a name is matched to the biggest account carrying it (Shopify → Shopify Inc.); when no big account has that name (e.g. Temu, Canva), the Actor uses the brand's domain instead and says so in the log. IDs and URLs are used exactly.

## `startUrls` (type: `array`):

Paste any adstransparency.google.com URL: an advertiser page, a domain search, a single ad page, or the political-ads page. Filters in the URL (region, format, platform, dates) are kept.

## `politicalAdsOnly` (type: `boolean`):

Only election ads (from verified election advertisers), with impression and spend ranges. With no domain or advertiser it lists the latest political ads in the chosen countries (US if none).

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

Where the ads were shown: 2-letter country codes like US, GB, DE, MY (or English names). Empty = anywhere. Several countries = ads shown in any of them.

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

Text = Search-style ads, Image = display and Shopping ads, Video = YouTube ads.

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

Only ads shown on this Google product.

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

Only ads shown on or after this date: YYYY-MM-DD, today, yesterday or -30 (30 days ago). The Center keeps ads from about 2020.

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

Only ads shown on or before this date (same formats).

## `maxAdsPerSearch` (type: `integer`):

Stop each domain, advertiser or URL after this many ads (newest first). 0 = all. Big brands run tens of thousands of ads.

## `maxAds` (type: `integer`):

Stop the whole run after this many ads. 0 = no limit (the maximum cost per run still applies).

## `includeAdContent` (type: `boolean`):

Read each ad's preview for its headline, description, call to action, landing page, image URLs, YouTube video and product title. Included in the ad price. Turn off for the fastest list of ad IDs and dates.

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

Extra paid event per ad: every country the ad ran in with first/last shown dates, impression ranges per country and per Google platform (EU and political ads), audience selection (demographics, locations, contextual, customer lists, interests), Google's topic label, the advertiser's legal name and country, and up to 5 ad variations with their copy. Single-ad URLs always include details.

## `allAdvertiserMatches` (type: `boolean`):

Big brands often have one advertiser account per country (e.g. several 'Booking.com'). On = scrape every account with that exact name; off = only the best match.

## `onlyNewAds` (type: `boolean`):

Skip ads already returned by an earlier run of this exact search (same domain/advertiser and filters). Schedule the Actor daily or weekly to get just the new creatives. You pay only for new ads.

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

Not needed — the Actor uses the run's own IP and switches to Apify datacenter proxies by itself if Google rate-limits it.

## Actor input object example

```json
{
  "domains": [
    "nike.com"
  ],
  "politicalAdsOnly": false,
  "regions": [
    "US"
  ],
  "adFormat": "ALL",
  "platform": "ALL",
  "maxAdsPerSearch": 100,
  "maxAds": 0,
  "includeAdContent": true,
  "includeDetails": false,
  "allAdvertiserMatches": false,
  "onlyNewAds": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per ad creative: advertiser, format, dates, ad copy, landing page, images.

## `reach` (type: `string`):

Countries, impression ranges, audience selection and topic (with full details on).

# 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"
    ],
    "regions": [
        "US"
    ],
    "maxAdsPerSearch": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("smoldesk/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"],
    "regions": ["US"],
    "maxAdsPerSearch": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("smoldesk/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"
  ],
  "regions": [
    "US"
  ],
  "maxAdsPerSearch": 100
}' |
apify call smoldesk/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

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