# Google Ads Transparency Scraper & Ad Monitor (`cylindrical_lighthouse/google-ads-transparency`) Actor

Scrape Google Ads Transparency Center ads by domain, advertiser or URL. Monitor competitors: get new, reactivated and ended ads since the last run.

- **URL**: https://apify.com/cylindrical\_lighthouse/google-ads-transparency.md
- **Developed by:** [Lighthouse Data](https://apify.com/cylindrical_lighthouse) (community)
- **Categories:** SEO tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Monitor

Get every ad a company runs on **Google Search, YouTube, Shopping, Maps and Play** from the public [Google Ads Transparency Center](https://adstransparency.google.com/). Look up competitors by **website domain, advertiser name, advertiser ID or pasted URL**. Put the Actor on a schedule to get a **change report**: which ads are **new**, which came **back**, and which have **ended** since the last run.

No login, no cookies, no browser. You get clean JSON, CSV or Excel, and you pay only for the ads you receive.

### What does Google Ads Transparency Scraper & Ad Monitor do?

- **Scrapes ad creatives** for any advertiser:
  - advertiser name and ID, the domain the ad points to, and the format (text, image or video)
  - first and last shown dates, and the number of days shown
  - the creative image URL or the Google preview URL
  - a deep link to the ad on adstransparency.google.com
- **Monitors competitors on a schedule.** Monitor mode remembers what it saw last time and returns only the **changes**:
  - `new`: ads that launched since the last run.
  - `reactivated`: ads that had stopped running (ended) and are running again.
  - `ended`: ads that stopped running.
- **Adds reach data (optional).**
  - All creative variations (A/B versions).
  - Per-country first and last shown dates.
  - For ads shown in the EU: impression ranges per country and per platform, from Google's DSA disclosures.
- **Accepts every input style in one run:**
  - `nike.com`
  - `HelloFresh`
  - `AR16735076323512287233`
  - a Transparency Center URL copied from your browser
- **Filters** by region (any country), platform (Search, YouTube, Shopping, Maps, Play), format, and date range.

### Why use it?

- **A change report, not just a dump.**
  - Besides **new** ads, it tells you when a competitor **stops** an ad or **brings one back**, which is how you spot winning creatives and seasonal campaigns.
  - Each run writes a per-competitor summary (active ads, new, ended).
- **Cheap to run weekly.** Watching 10 typical competitors costs about $0.10 a week: one small check per competitor plus the changes it finds.
- **Fast and reliable.** It talks directly to the Transparency Center's own data API over plain HTTPS: about 1,000 ads in under a minute, with automatic retries and IP rotation when Google rate-limits.
- **Honest pricing.** Proxy traffic and platform compute are included in the per-event price and never billed to you separately.
- **Built for automation and AI agents.** Every input and output field is documented, the default input costs about $0.03, and results are ready for Make, Zapier, Google Sheets, webhooks or the Apify MCP server.

### Use cases

- **Competitor ad monitoring.** Get a weekly list of the ads your competitors launched, paused or relaunched, delivered to Slack, email or a spreadsheet.
- **Creative research and swipe files.** Pull a brand's image and video creatives, and sort by `daysShown`: ads that run for months are the ones that work.
- **Agency reporting.** Monitor every client's competitors under one schedule, with a separate memory per client.
- **Market and media research.** See which countries and Google surfaces a brand targets, and how many impressions its EU ads get.
- **Sales intelligence.** Check whether a prospect advertises on Google at all, and how actively.
- **AI agents.** Ask "What YouTube ads is Nike running in Germany?" and let your agent call this Actor through MCP.

### How to use it

1. Click **Try for free** (or **Start**).
2. Enter one or more **domains** (e.g. `nike.com`), **advertiser names**, **advertiser IDs** or **Transparency Center URLs**.
3. Optionally set **Region**, **Google platform**, **Ad format** or a **date range**.
4. Click **Start**, then download the results as JSON, CSV or Excel, or read them through the API.

#### Scrape example

```json
{
    "domains": ["nike.com"],
    "advertiserNames": ["HelloFresh"],
    "region": "US",
    "platform": "YOUTUBE",
    "maxAdsPerQuery": 50
}
```

#### Set up a weekly competitor monitor (recommended)

1. Set **Mode** to `monitor` and list your competitors' domains:

   ```json
   {
       "mode": "monitor",
       "domains": ["competitor-one.com", "competitor-two.com", "competitor-three.com"],
       "region": "US",
       "includeEndedAds": true,
       "monitorStoreName": "acme-competitor-ads"
   }
   ```

2. Click **Save as a new task**, then open the task's **Schedules** tab and add a schedule, e.g. **every Monday at 07:00** (cron `0 7 * * 1`).

3. Add an integration to the task, for example Slack, email, Google Sheets or a webhook, so each week's changes reach you automatically.

- **The first run** saves the current ads as the `baseline` (up to `maxAdsPerQuery` are returned and all of them are remembered).
- **Every later run** returns only `new`, `reactivated` and `ended` ads.
- **Separate memories:** use a different **Monitor memory name** per client or project.

### Input

| Field | Type | Description | Example |
|---|---|---|---|
| `mode` | string | `scrape` (all matching ads) or `monitor` (only changes since the last run) | `"monitor"` |
| `domains` | string\[] | Advertiser website domains. Ads from every advertiser account pointing to the domain. An input with no lookups at all runs the example `nike.com` | `["nike.com"]` |
| `advertiserNames` | string\[] | Brand or company names, resolved to the verified advertiser account(s) with the most ads | `["HelloFresh"]` |
| `advertiserIds` | string\[] | Google advertiser IDs (`AR` + 20 digits) | `["AR16735076323512287233"]` |
| `startUrls` | URL\[] | Transparency Center advertiser, creative or domain URLs | `[{"url": "https://adstransparency.google.com/advertiser/AR16735076323512287233"}]` |
| `region` | string | ISO country code or `anywhere` | `"DE"` |
| `platform` | string | `ALL`, `SEARCH`, `YOUTUBE`, `SHOPPING`, `MAPS`, `PLAY` | `"YOUTUBE"` |
| `format` | string | `ALL`, `TEXT`, `IMAGE`, `VIDEO` | `"VIDEO"` |
| `dateFrom` / `dateTo` | string | Only ads shown within this window (YYYY-MM-DD, last ~12 months; scrape mode only) | `"2026-06-01"` |
| `maxAdsPerQuery` | integer | Max records per domain/advertiser/URL (default 20; 0 = no limit). Caps your cost | `100` |
| `maxAdvertisersPerName` | integer | Advertiser accounts to use per name, biggest first | `3` |
| `includeDetails` | boolean | Add variations, per-country dates and EU impressions (extra event) | `true` |
| `monitorStoreName` | string | Named key-value store that holds the monitor memory | `"acme-competitor-ads"` |
| `includeEndedAds` | boolean | Monitor mode: also return ads that stopped running | `true` |
| `endedAfterDays` | integer | An ad counts as ended after this many days without being shown | `3` |
| `baselineLookbackDays` | integer | First monitor run: ads shown within this many days form the baseline | `30` |
| `maxScanPerQuery` | integer | Monitor mode: cap on live ads read per query and run (one monitor check per started 1,000) | `3000` |
| `proxyConfiguration` | object | Proxy settings. Residential is the default and recommended | `{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}` |

### Output

Each dataset item is one ad. This is a real record for `nike.com`:

```json
{
    "creativeId": "CR18136630512767205377",
    "advertiserId": "AR18378488041124659201",
    "advertiserName": "Nike Retail BV",
    "domain": "nike.com",
    "format": "TEXT",
    "firstShownAt": "2025-09-19T13:06:18.353Z",
    "lastShownAt": "2026-09-29T21:26:59.590Z",
    "daysShown": 321,
    "imageUrl": "https://tpc.googlesyndication.com/archive/simgad/4610137042240554284",
    "imageWidth": 348,
    "imageHeight": 421,
    "previewUrl": null,
    "adUrl": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR18136630512767205377",
    "queryType": "domain",
    "queryValue": "nike.com",
    "regionFilter": null,
    "platformFilter": null,
    "changeType": null,
    "variationCount": null,
    "variations": null,
    "regions": null,
    "impressionsMin": null,
    "impressionsMax": null,
    "url": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR18136630512767205377",
    "scrapedAt": "2026-09-29T21:58:29.447Z"
}
```

With **Include ad details** on, the detail fields are filled. This excerpt is from a real EU video ad:

```json
{
    "variationCount": 5,
    "regions": [
        {
            "regionCode": "ES",
            "regionName": "Spain",
            "firstShownDate": "2025-09-15",
            "lastShownDate": "2026-09-29",
            "impressionsMin": 10000000,
            "impressionsMax": null,
            "platforms": [
                { "platform": "MAPS", "impressionsMin": 10000000, "impressionsMax": null },
                { "platform": "YOUTUBE", "impressionsMin": 10000000, "impressionsMax": null },
                { "platform": "SEARCH", "impressionsMin": 175000, "impressionsMax": 200000 }
            ]
        }
    ],
    "impressionsMin": 10000000,
    "impressionsMax": null
}
```

**Field notes:**

- In monitor mode, `changeType` is `baseline`, `new`, `reactivated` or `ended`.
- `ended` records carry the ad's IDs, advertiser, format and dates. Google no longer serves their creative, so the image fields are `null`.
- Impression ranges are published by Google only for ads shown in the EU. `impressionsMax: null` with a `impressionsMin` means "at least". Missing values are `null`, never guessed.
- The **SUMMARY** record in the run's key-value store lists, per query:
  - the resolved advertisers and Google's total-ads range
  - counts of ads scanned, returned, new, reactivated and ended
  - the active ads in memory
  - any warning

The dataset has three views: **Ads**, **Monitor changes**, and **Reach and impressions**.

### Pricing

This Actor uses **pay-per-event** pricing. You pay for what you get; platform compute and proxy traffic are included.

Prices by Apify plan (discount tiers):

| Event | When it is charged | Free | Bronze | Silver | Gold | Platinum | Diamond |
|---|---|---|---|---|---|---|---|
| Run start | Once per run | $0.005 | $0.005 | $0.005 | $0.005 | $0.005 | $0.005 |
| Ad | Each ad saved (scrape mode: every ad; monitor mode: baseline, new and reactivated ads) | $0.0012 | $0.0010 | $0.0009 | $0.0008 | $0.0008 | $0.0008 |
| Ad details | Each ad, only when **Include ad details** is on | $0.002 | $0.0018 | $0.0015 | $0.0012 | $0.0012 | $0.0012 |
| Monitor check | Monitor mode: per query and run, for each started 1,000 live ads read to find the changes | $0.008 | $0.008 | $0.008 | $0.008 | $0.008 | $0.008 |
| Ended ad | Each `ended` record in monitor mode | $0.0005 | $0.0004 | $0.0003 | $0.0003 | $0.0003 | $0.0003 |

**Why a monitor check?**

- To tell you which ads are new and which ended, the monitor reads every ad a competitor is currently running, not just the ones it returns.
- For a typical competitor with fewer than 1,000 live ads, that is one check per run.

**Cost examples (Free plan prices):**

- **Default input** (20 ads for `nike.com`): $0.005 + 20 × $0.0012 = **$0.029**.
- **1,000 ads** from one advertiser: **$1.205**.
- **1,000 ads with details:** **$3.205**.
- **Weekly monitor of 10 competitors** (each under 1,000 live ads) finding 15 new, 2 reactivated and 5 ended ads:
  - $0.005 + 10 × $0.008 + 17 × $0.0012 + 5 × $0.0005 = **$0.11 per run**
  - about **$0.47 a month**
- **A quiet week** for the same 10 competitors: $0.005 + 10 × $0.008 = **$0.085**.
- **One big brand** with 2,500 live ads: 3 checks = **$0.024 per run**, plus its changes.

**Staying in control of spend:**

- Set **Maximum cost per run** in the run options. The Actor stops cleanly at that limit and never fetches data it cannot charge for.
- `maxAdsPerQuery` caps the records per query.
- `maxScanPerQuery` caps the monitor checks per query.

### FAQ

**Is it legal to scrape the Google Ads Transparency Center?**

- Google publishes the Ads Transparency Center so that anyone can see who advertises and what they show. In the EU it is the ad repository required by the Digital Services Act.
- This Actor reads only that public data. It never logs in, uses no cookies and solves no CAPTCHAs.
- Google's Terms of Service restrict automated access to its services, so review your own use case.
- Results can contain personal data: some verified advertisers are individuals (for example sole traders or political candidates), and their names are published by Google. Personal data is protected by GDPR and other regulations. Do not process it unless you have a legitimate reason. If you are unsure, consult your lawyers.

**Is this an official Google product?**
No. This Actor is independent and is not affiliated with, endorsed by or sponsored by Google LLC. "Google" and "Google Ads" are trademarks of Google LLC, used here only to describe the public data source.

**How does monitor mode decide what is "new" or "ended"?**

- **New:** an ad first shown after you started monitoring the query.
- **Reactivated:** an ad the monitor saw end that is running again.
- **Missed earlier?** Google reorders ads while they are being read, and very large advertisers can exceed the scan cap. An older ad that was running all along but missed by an earlier check is added to the memory silently, not reported as a change. The SUMMARY counts these as `absorbed`.
- **Ended:** an ad from the memory that Google has not shown for `endedAfterDays` days (default 3).
- Each change is reported exactly once. If a run hits `maxAdsPerQuery` or your cost limit, the remaining changes are reported next time.

**Where is the monitor memory stored? Can I reset it?**

- It lives in the named key-value store set in **Monitor memory name**, in your own Apify account, with one record per query and filter combination.
- To start over, delete that store or use a new name.
- Changing the region, platform or format of a query starts a new memory for it.

**Why is there no ad text for text ads?**
Google archives most search text ads as **images**, so the headline and description are in `imageUrl`, not in a text field. Video and rich ads come with a Google `previewUrl`.

**Why do I get fewer ads than Google's total?**

- `maxAdsPerQuery` limits each query (default 20). Set it higher, or to `0` for everything.
- Region, platform, format and date filters narrow the results, like on the website.

**Can I use my own proxies?**
Yes, set them in **Proxy configuration**. Residential proxies work best, because Google rate-limits datacenter IPs quickly. The Actor retries on a new IP automatically.

### Limitations

- **Dates:** the date filter covers roughly the last 12 months only. Google does not serve older windows, so older start dates are moved forward with a warning.
- **Ad copy:** text-ad copy comes as an image, not as text (see FAQ). There is no ad spend, except that EU ads carry impression ranges.
- **Platform data:** Google reports platform (Search, YouTube and so on) only for ads shown since September 2023.
- **Advertiser names:** a name resolves to verified advertiser accounts only. Very generic names may pick the wrong account; use a domain or advertiser ID to be exact.
- **Monitor scan cap:** monitor mode reads up to `maxScanPerQuery` live ads per query per run (default 3,000, i.e. at most 3 monitor checks). If a giant advertiser exceeds it, ended-ad detection is skipped for that run and the log says so. Monitoring a very large brand reads thousands of ads, which takes a few minutes.
- **Data freshness:** the data is exactly what Google publishes, including its approximate ad-count and impression ranges.

### Changelog

See the [changelog](./CHANGELOG.md) (also on the **Changelog** tab).

### Support

Found a bug, or need a field or filter? Open an issue on the **Issues** tab. We respond within 48 hours. Feature requests are welcome.

# Changelog

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

# Actor input Schema

## `mode` (type: `string`):

'scrape' returns every matching ad (up to the per-query limit). 'monitor' compares with the previous run of the same query and returns only changes: ads that are new, reactivated or ended. The first monitor run returns the current ads as a 'baseline'. Example: "monitor" for a weekly competitor-ads report.

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

Website domains whose Google ads you want, one per line. Returns ads from every advertiser account that points to this domain. Protocol, 'www.' and paths are stripped automatically. If you give no domain, name, ID or URL at all, the example 'nike.com' is used. Example: "nike.com".

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

Company or brand names, one per line. Each name is resolved to the matching verified advertiser account(s) with the most ads. Use 'Advertisers per name' to pull more than one account. Example: "HelloFresh".

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

Google advertiser IDs: 'AR' followed by 20 digits, as shown in a Transparency Center advertiser URL. Example: "AR16735076323512287233" (Nike, Inc.).

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

Paste advertiser, creative or domain-search URLs copied from adstransparency.google.com. The advertiser ID or domain is extracted automatically. Example: "https://adstransparency.google.com/advertiser/AR16735076323512287233?region=US".

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

Only ads shown in this country. Use 'anywhere' for all regions. Value is an ISO 3166 two-letter code. Example: "US" or "DE".

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

Only ads shown on this Google surface. Example: "YOUTUBE" for YouTube ads only. Note that Google only reports platforms for ads shown since September 2023.

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

Only ads of this format. Example: "VIDEO" for video ads only.

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

Only ads that were shown on or after this date (YYYY-MM-DD). Google only supports roughly the last 12 months. Needs 'Shown until' too, or today is used. Ignored in monitor mode. Example: "2026-06-01".

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

Only ads that were shown on or before this date (YYYY-MM-DD). Defaults to today when 'Shown from' is set. Ignored in monitor mode. Example: "2026-09-30".

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

Maximum number of ad records to return for each domain, advertiser or URL. Caps your cost: you pay per ad returned. In monitor mode it caps the changes returned per query (the rest are reported next run). 0 means no limit. Example: 100.

## `maxAdvertisersPerName` (type: `integer`):

How many advertiser accounts to use for each advertiser name, biggest first. Large brands often run separate accounts per country. Example: 3.

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

Makes one extra request per ad to add all creative variations and per-country data: first and last shown date per country, plus impression ranges split by platform for ads shown in the EU. Charged as a separate 'ad-details' event. Example: true.

## `monitorStoreName` (type: `string`):

Name of the key-value store that remembers what each query returned in previous runs. Every query (domain, advertiser plus filters) keeps its own memory inside it. Use a different name per project or client if you want separate histories. Example: "client-acme-ads-monitor".

## `includeEndedAds` (type: `boolean`):

In monitor mode, also return ads that stopped running since the previous run (changeType 'ended'). Charged as the cheaper 'ended-ad' event. Example: true.

## `endedAfterDays` (type: `integer`):

An ad counts as ended once Google has not shown it for this many days. Lower values report endings faster; higher values avoid false alarms for ads that pause briefly. Example: 3.

## `baselineLookbackDays` (type: `integer`):

On the first monitor run of a query, ads shown within this many days count as the current baseline. Example: 30.

## `maxScanPerQuery` (type: `integer`):

Monitor mode reads every ad the advertiser is currently running to find what changed, and charges one 'monitor-check' per started 1,000 ads read per query. This caps how many ads are read per query and run, and so that cost. If a query hits the cap, ended-ad detection is skipped for that run. Example: 3000.

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

Google rate-limits datacenter IPs heavily, so Residential proxies are the default and recommended. Proxy traffic is included in the price and never billed to you separately. Example: {"useApifyProxy": true, "apifyProxyGroups": \["RESIDENTIAL"]}.

## Actor input object example

```json
{
  "mode": "scrape",
  "domains": [
    "nike.com"
  ],
  "region": "anywhere",
  "platform": "ALL",
  "format": "ALL",
  "maxAdsPerQuery": 20,
  "maxAdvertisersPerName": 1,
  "includeDetails": false,
  "monitorStoreName": "google-ads-transparency-monitor",
  "includeEndedAds": true,
  "endedAfterDays": 3,
  "baselineLookbackDays": 30,
  "maxScanPerQuery": 3000,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

One row per ad creative: advertiser, format, first and last shown, creative image and link.

## `changes` (type: `string`):

Monitor mode: baseline, new, reactivated and ended ads per competitor since the last run.

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

With 'Include ad details': variations, countries and EU impression ranges per ad.

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

Per query: resolved advertisers, Google's total-ads range, ads scanned and returned, new/reactivated/ended counts, and warnings.

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

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

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

```

## MCP server setup

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

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/7lV31VS4bfAPpwGyK/builds/zs8or5HyHV4uXUZqN/openapi.json
