# Google Ads Scraper (`mlg14/google-ads-scraper`) Actor

Collect public Google Ads Transparency Center creatives and advertiser summaries by domain, advertiser ID, or search term. Export dates, formats, previews, reach, and advertiser identity.

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

## Pricing

$1.60 / 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

Scrape public Google Ads Transparency Center creatives by advertiser ID, destination domain, or search term. Export Google Ads data to JSON, CSV, or Excel for competitive research, creative review, and advertiser checks. This scraper is an alternative to building and maintaining a custom connection to the site's public search interface.

The actor returns individual ad creatives or one row per advertiser. Creative rows include the ad ID, advertiser identity, format, activity dates, days served, direct image or hosted preview link, and a link back to the public record. Optional full details add the available creative variations and country reach. No account on the source site is needed.

### What data can you extract from Google Ads?

Choose **ads** for creative records or **advertisers** for account summaries. A dataset contains one kind of row per run, selected by `resultType`. Empty fields are returned as `null` when the public source does not provide them. The two modes share the public advertiser ID and requested region.

| Field | Description | Example |
| --- | --- | --- |
| `creativeId` | Public creative identifier | `CR15481450763665801217` |
| `advertiserId` | Public advertiser identifier | `AR16735076323512287233` |
| `advertiserName` | Name shown with a creative | Available in creative rows |
| `domain` | Matched destination domain when exposed | `example.com` |
| `format` | Creative type | `IMAGE` |
| `firstShown` | First recorded activity in UTC | `2026-08-25T21:30:48.312Z` |
| `lastShown` | Last recorded activity in UTC | `2026-09-27T04:15:56.459Z` |
| `shownForDays` | Number of days on which the ad was served | `8` |
| `previewType` | Type of preview returned | `image` |
| `imageUrl` | Direct image asset, when present | Hosted image URL |
| `previewUrl` | Hosted preview, when present | Hosted preview URL |
| `width`, `height` | Pixel dimensions in the image markup | `348`, `200` |
| `googleCreativeId` | Creative identifier embedded in some previews | String or `null` |
| `googleCustomerId` | Customer identifier embedded in some previews | String or `null` |
| `adGroupId` | Ad group identifier embedded in some previews | String or `null` |
| `versionId` | Version identifier embedded in some previews | String or `null` |
| `adUrl` | Direct link to the public creative page | Transparency Center URL |
| `region` | Region selected for the run | `US` |
| `variationCount` | Number of returned variations with full details | `3` |
| `variations` | Preview information for every available variation | Array of objects |
| `regionsShown` | Country reach with last shown dates | Array of objects |
| `containsSyntheticMedia` | Source indicator shown in full details | `false` |
| `name` | Displayed name in advertiser mode | Public advertiser name |
| `countryCode` | Advertiser billing or disclosure country | `US` |
| `approxAdCountLow` | Lower bound of the source's approximate ad count | `7000` |
| `approxAdCountHigh` | Upper bound of the source's approximate ad count | `8000` |
| `legalName` | Disclosed legal name, when available | Public legal name |
| `verified` | Verification status reported by the source | `true` |
| `matchedQuery` | Search term or domain that produced the match | `example.com` |
| `advertiserUrl` | Link to the public advertiser page | Transparency Center URL |

Activity dates describe what the public service reports. `shownForDays` is a count of served days; it is not the calendar difference between `firstShown` and `lastShown`. An ad could be shown intermittently. Likewise, approximate ad-count bounds are ranges from the source, not an exact census.

### How to scrape Google Ads

1. Enter an advertiser ID, an exact destination domain, a search term, or a copied Transparency Center URL. An advertiser ID is the `AR...` value in a public advertiser URL.
2. Choose a region. `US` is preselected; `ANYWHERE` searches without a country restriction. Set `resultType` to **ads** or **advertisers**.
3. Set `maxAdsPerSearch` and `maxItems` to the amount of data you need. Add a format, platform, or date window if you want a narrower creative set.
4. Start the actor. Results are written as each row is collected. Download the dataset as JSON, CSV, or Excel, or retrieve it through the platform API.

Start with one exact advertiser ID when you already know the account. Use an exact domain when you want to see creatives from multiple advertiser accounts pointing to the same destination. Use a search term when you do not know the ID; the actor resolves public advertiser suggestions and checks the most prominent matches. Search terms can match similarly named accounts, so inspect `advertiserId`, `advertiserName`, and the advertiser page before combining records in a report.

### Input

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `queries` | String list | Empty | Terms or domains resolved through public suggestions. |
| `domains` | String list | Empty | Exact destination domains. |
| `advertiserIds` | String list | Sample ID | Public `AR...` IDs. |
| `startUrls` | URL list | Empty | Public advertiser or creative URLs, plus search URLs with `domain` or `query`. |
| `resultType` | Select | `ads` | Creative rows or advertiser summaries. |
| `region` | Select | `US` | Supported country code or `ANYWHERE`. |
| `platforms` | Select list | Empty | Search, YouTube, Shopping, Maps, or Play; empty means all. |
| `adFormat` | Select | `ALL` | `TEXT`, `IMAGE`, `VIDEO`, or all formats. |
| `startDate` | Date text | Empty | Keep ads whose reported activity overlaps this date or later. |
| `endDate` | Date text | Empty | Keep ads whose reported activity overlaps this date or earlier. |
| `maxAdsPerSearch` | Integer | `100` | Maximum ad rows read for each target and selected platform. |
| `maxAdvertisersPerQuery` | Integer | `5` | Maximum suggested advertiser IDs inspected per term; at most 10. |
| `maxItems` | Integer | `100` | Total dataset-row cap; zero removes this total cap. |
| `includeDetails` | Boolean | `false` | Fetch variations and country reach with an extra request per ad. |
| `proxyConfiguration` | Object | Platform proxy | Network settings; datacenter access is tried first. |

At least one of `queries`, `domains`, `advertiserIds`, or `startUrls` is required. The prefilled ID demonstrates the input shape; replace it to focus on your own target. When several input lists are supplied, the actor processes advertiser IDs, then domains, then individual creative URLs, deduplicating creatives by ID across results. A total cap can end the run before later targets are reached. For balanced coverage, run targets separately or raise `maxItems`.

```json
{
  "advertiserIds": ["AR16735076323512287233"],
  "resultType": "ads",
  "region": "US",
  "adFormat": "IMAGE",
  "maxAdsPerSearch": 100,
  "maxItems": 100,
  "includeDetails": false
}
```

To inspect a destination domain across accounts, use `domains` instead of `advertiserIds`. Domain results retain the matching domain in each row when the source returns one. For a compact account check, set `resultType` to `advertisers`; the actor looks up each advertiser and obtains the source's approximate count bounds. For an individual creative URL, paste the full public URL into `startUrls`.

### Output example

The following fields come from one public image-creative result in the validated 40-row advertiser run. The advertiser name is omitted from this shortened example; the dataset includes it. Preview IDs are `null` when they are not present in image markup.

```json
{
  "creativeId": "CR15481450763665801217",
  "advertiserId": "AR16735076323512287233",
  "format": "TEXT",
  "firstShown": "2026-08-25T21:30:48.312Z",
  "lastShown": "2026-09-27T04:15:56.459Z",
  "shownForDays": 8,
  "previewType": "image",
  "imageUrl": "https://tpc.googlesyndication.com/archive/simgad/12219066510995162321",
  "previewUrl": null,
  "width": 348,
  "height": 200,
  "adUrl": "https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR15481450763665801217?region=US",
  "region": "US"
}
```

This example illustrates why the public format and preview representation should be interpreted separately: the source marks this creative as `TEXT`, while its preview is an image. A preview can also be hosted behind a URL rather than exposed as a direct image. Consumers should use `format` for the source's classification and `previewType`, `imageUrl`, and `previewUrl` to decide how to display a preview.

In advertiser mode, the actor emits `advertiserId`, `name`, `countryCode`, `approxAdCountLow`, `approxAdCountHigh`, `legalName`, `verified`, `matchedQuery`, `advertiserUrl`, and `region`. Counts can change between runs as activity changes. `matchedQuery` is `null` when the row came from a direct ID rather than a term or domain.

### Use cases

- Competitive researchers can compare the creatives, formats, and served-day counts for public advertiser accounts in a given country.
- Creative teams can gather image assets and hosted previews for a review board, then inspect full variations for selected ads.
- Sales operations can check a list of public advertiser IDs and receive compact account rows with approximate ad-count ranges.
- Market analysts can compare public ad activity across destination domains, including domains associated with several advertiser IDs.
- Compliance reviewers can keep a dated record of public creative IDs and URLs for their own review process.
- Reporting teams can append scheduled dataset exports and compare newly observed creative IDs with prior exports.

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

The actor's current result event is **$0.0016 per dataset row**, or **$1.60 per 1,000 results**. A 40-row run is about **$0.064**; 500 rows are about **$0.80**; 5,000 rows are about **$8.00**. The actor has no separate result event for full details: turning on `includeDetails` increases the number of source requests and usually increases run time, while the row count remains the billing unit. The price displayed on the actor's Pricing tab is authoritative if pricing changes later.

The `maxItems` input is the simplest way to cap delivered rows. `maxAdsPerSearch` limits the work for each target, while `maxAdvertisersPerQuery` limits how many accounts a free-text term can expand into. If your run has a maximum charge configured on the platform, the actor stops when the dataset push reports that the charge limit was reached. A run with no matching public ads may finish with zero rows.

### Tips for best results

Use the most specific input you have. An exact advertiser ID avoids name collisions. An exact domain is useful when the destination is the important entity, but it can return ads from several accounts and languages. A text query is broader: public suggestions can include similar names, regional accounts, or unrelated near matches. Check the IDs before treating all results as one organization.

Keep `includeDetails` off for exploratory runs. Search results already include IDs, dates, format, and a preview. Turn details on when the additional variations or country list are actually needed, such as a small final selection for a creative report. Each detailed row requires one more lookup, so the elapsed time grows with the number of rows.

Choose a region deliberately. Country scope affects which ads the public service returns, and the same creative may appear in several country-specific runs. `ANYWHERE` is useful for discovery, but country runs are easier to compare. Supported codes are `US`, `GB`, `CA`, `AU`, `DE`, `FR`, `IN`, `BR`, `JP`, `IT`, `ES`, `NL`, `MX`, `SG`, and `ZA`. A code outside this list must be changed to a supported value or `ANYWHERE`.

Platform selections are queried separately and deduplicated by creative ID. When you select several platforms, `maxAdsPerSearch` applies to each selected platform for each target, while `maxItems` remains the total output cap. Platform filtering follows the public site's own coverage; older ads may not carry complete platform information. The date fields use the public activity window: an ad is kept if that window overlaps your chosen start and end dates. Dates do not mean the creative ran continuously during the interval.

### Limits

This actor reads publicly visible records only. The public source decides which ads and accounts are available, when records are updated, and whether counts are precise. The advertiser count is a lower and upper bound, not an exact number. The source can also return an empty result for a valid ID, domain, or country if no public ads meet the filters.

Preview data varies by creative. Direct image links and dimensions appear when the public preview contains image markup. Text, video, and other renderings may instead provide a hosted preview URL. The identifiers embedded in a hosted preview URL are absent from many image rows. Do not use an empty preview ID to conclude that an ad itself is missing; use `creativeId` as the public record key.

Full-detail `regionsShown` reflects only the country reach exposed for that creative. Each entry retains a numeric `geoCriteriaId`; the actor translates supported country IDs to `region` codes and leaves other codes as `null` rather than guessing. Full-detail variations can be empty when the public lookup does not expose them. Some individual creative URLs can also fail to return a detail record, even when search still shows a preview.

The actor paginates using the source's returned page token and stops at input limits. It does not claim to retrieve ads hidden by the source, ads that require an account, or every creative that ever ran. Large, broad domains may produce many matches; increase limits or narrow by region, format, and platform when you need a manageable dataset. Search results can shift while a long run is in progress, so deduplication avoids repeated creative IDs within a run.

### Use with scheduled workflows

A scheduled run can export the current public records each day or week. Compare `creativeId` values across datasets to find newly observed ads, and compare `lastShown` values to see which records changed. For an advertiser check, compare the approximate count range and public ID rather than treating a small count change as a precise increase. Keep the same input and region across snapshots so the comparison is meaningful.

Example requests for an automated workflow are: “Collect up to 100 public image creatives for this advertiser ID in the US and export the dates and image links,” and “Return advertiser summaries for these public IDs with approximate ad-count ranges.” Supply the IDs or domains directly in the input so the scheduled run is reproducible.

### FAQ

**Do I need an account on the source site?** No. The actor reads the public Transparency Center interface. It does not request private account data.

**Is it legal to collect these records?** The records are publicly visible, but you are responsible for the applicable source terms, local law, and any privacy requirements. Use public advertiser and creative data responsibly, and avoid using the output to infer private information about individuals.

**Do I need to configure a proxy?** The default uses the platform proxy. The fetch layer begins with datacenter access and can rotate or escalate if it encounters a block. Leave the default in place unless you have a tested network requirement.

**How fast is a run?** Speed depends on the number of targets, pages, filters, and detail lookups. A 40-row creative validation completed successfully on the platform. Full details add a lookup for every returned creative and therefore take longer than a preview-only run.

**Can I schedule or monitor changes?** Yes. Schedule repeated runs and compare creative IDs between datasets. This actor does not maintain a persistent seen-ID list or emit only-new rows itself; maintain that comparison in your own workflow.

**Can I export to a spreadsheet?** Yes. Download the default dataset as CSV or Excel, or send dataset items through an integration. Nested detail arrays are easiest to inspect in JSON.

**Why are some fields empty?** The public service does not expose every preview identifier, domain, dimension, or country detail for every creative. Empty optional fields are represented as `null` and are not estimated.

**Are advertiser counts exact?** No. The public service provides approximate lower and upper bounds. Use them for broad comparisons, and keep both fields when exporting data.

### Integrations

Run the actor manually or on a schedule, retrieve results through the platform API, and connect completed runs to webhooks or workflow services. JSON preserves nested creative variations and country reach; CSV and Excel work well for the flat fields. The default dataset URL is available in the actor output. For reliable joins across runs, store `creativeId` with each creative row and `advertiserId` with each account row.

### Support

Open an issue on the Issues tab with the input, public URL, region, and the field that appears wrong. We reply within 24 hours and add fields on request.

# Actor input Schema

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

Names or domains to resolve to advertisers and their public ads.

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

Destination domains to search exactly, such as example.com.

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

Public advertiser IDs beginning with AR.

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

Transparency Center advertiser or creative URLs, or URLs containing a domain or query parameter.

## `resultType` (type: `string`):

Return ad creatives or one summary per advertiser.

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

Country where ads were shown, or ANYWHERE for all available regions.

## `platforms` (type: `array`):

Limit ads to selected surfaces. Empty means all surfaces.

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

Return all, text, image, or video creatives.

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

Keep ads whose activity overlaps this YYYY-MM-DD date or later.

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

Keep ads whose activity overlaps this YYYY-MM-DD date or earlier.

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

Maximum creatives read for each advertiser or domain and each selected platform.

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

Maximum suggested advertiser accounts to inspect for each search term.

## `maxItems` (type: `integer`):

Stop after this many dataset rows across all targets. Zero means no total cap.

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

Add all available creative variations and country reach to each ad. This makes an extra request per ad.

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

Proxy settings. The scraper begins with datacenter access and escalates on blocks.

## Actor input object example

```json
{
  "advertiserIds": [
    "AR16735076323512287233"
  ],
  "resultType": "ads",
  "region": "US",
  "platforms": [],
  "adFormat": "ALL",
  "maxAdsPerSearch": 100,
  "maxAdvertisersPerQuery": 5,
  "maxItems": 100,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Scraped creatives or advertiser summaries in the default dataset.

# 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 = {
    "advertiserIds": [
        "AR16735076323512287233"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mlg14/google-ads-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 = { "advertiserIds": ["AR16735076323512287233"] }

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

```

## MCP server setup

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