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

Scrape Google Ads Transparency Center data: text, image, and video ads with clean headlines, body copy, CTAs, and business details. Get political ad spend and impression ranges most scrapers miss, plus advertiser verification info.

- **URL**: https://apify.com/api\_creators/google-ads-scraper.md
- **Developed by:** [API Creators](https://apify.com/api_creators) (community)
- **Categories:** Developer tools, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 4 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.30 / 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Google Ads Scraper

Scrape every ad an advertiser is running on the [Google Ads Transparency Center](https://adstransparency.google.com/) — text, image, and video ads — and get back headlines, body copy, calls-to-action, business details, click URLs, creative images, and region-by-region reach. For political ads, you also get the spend and impression ranges Google publishes, which most Google Ads scrapers skip entirely.

Just give it an advertiser's Transparency Center link, their website domain, or even just their name, and it returns one clean row of data per ad. No login required, no browser needed on your end — just structured, ready-to-use Google Ads data.

### ✨ Why use this Google Ads Transparency Center scraper

- **Political ad spend and impressions.** Political ad data usually stops at the creative itself. This tool also returns spend ranges (with currency) and impression ranges for political ads, plus the regions they were targeted at.
- **Clean ad copy, not garbled screenshots.** Headline, body, call-to-action, business name, address, and category come back as clean structured text for the vast majority of ads — including image-based product ads, not just plain text ads.
- **Accurate text recovery even for image-only ads.** For the smaller set of ads where only a screenshot is available, built-in text recognition extracts the copy — and it's on request only, so you're never charged for it on ads that don't need it.
- **No duplicate results.** Ad platforms often serve the same creative variation more than once; duplicates are filtered out before they reach your dataset.
- **Direct video files, not just a YouTube link.** Video ads resolve to a downloadable video URL, not only an embed reference.
- **Advertiser details included.** Legal business name, home country, and verification status are included automatically, at no extra cost.
- **Fast by default.** A lightweight listing mode returns every ad from an advertiser in seconds when you don't need full ad copy — ideal for large-scale monitoring.

### 🚀 Quick start

The simplest input is a Transparency Center link, exactly as it appears in your browser after picking an advertiser:

```json
{
  "startUrls": [
    { "url": "https://adstransparency.google.com/advertiser/AR18135649662495883265?region=anywhere" }
  ]
}
```

Don't have the link handy? A plain advertiser name or website domain works too:

```json
{
  "advertiserNames": ["Nike"],
  "domains": ["nike.com"]
}
```

If multiple advertiser accounts share a name, every matching account is included automatically — no need to pick the right one yourself.

### 🎛️ Run modes

- **Full detail (default).** Every ad's complete copy, images, region-by-region reach, and audience targeting.
- **Fast listing mode** (`skipDetails: true`). Every ad an advertiser is running, in a fraction of the time — advertiser, format, dates, and preview image, without opening each ad individually. Ideal for large accounts or frequent monitoring runs.
- **Political mode** (`topic: "political"`). Surfaces spend and impression ranges directly in the results.
- **Text recovery** (`ocr: true`). Turn this on if you specifically need text pulled from image-only ads that don't otherwise expose readable copy. Off by default.

### 📥 Input

| Field | What it does |
|---|---|
| `startUrls` | One or more Google Ads Transparency Center links |
| `advertiserNames` | Plain advertiser names — matching accounts are resolved automatically |
| `domains` | Advertiser website domains, e.g. `"nike.com"` |
| `resultsLimit` | Cap the number of ads returned per input |
| `skipDetails` | Fast listing-only mode |
| `topic` | `"all"` or `"political"` |
| `ocr` | Recover text from image-only ads (off by default) |
| `shouldDownloadAssets` | Save a permanent copy of video files |
| `shouldDownloadPreviews` | Save a permanent copy of each ad's preview |
| `proxyConfiguration` | Proxy setup — required, and enabled by default |
| `assetProxyConfiguration` | Optional separate proxy for preview/image/video downloads — roughly 90% of all traffic, so pointing it at cheap flat-rate bandwidth cuts proxy cost sharply. Can also be set once for every run via the `ASSET_PROXY_URL` environment variable |

Full field details and defaults are in the input form above.

### 📤 Output

One dataset row per ad. A real example (trimmed for space):

```json
{
  "adLibraryUrl": "https://adstransparency.google.com/advertiser/AR18135649662495883265/creative/CR17043350830998093825",
  "advertiserId": "AR18135649662495883265",
  "advertiserName": "SociallyUP",
  "advertiserLegalName": "SociallyUP",
  "advertiserLocation": "United States",
  "creativeId": "CR17043350830998093825",
  "format": "TEXT",
  "firstShown": "2023-09-19T07:00:00.000Z",
  "lastShown": "2026-03-03T00:27:37.471Z",
  "creativeRegions": ["United States"],
  "regionStats": [{ "regionCode": "US", "regionName": "United States", "lastShown": "2026-03-02" }],
  "variations": [
    {
      "headline": "{KeyWord:Bloomington Apartments}",
      "body": "With Rentals Close to the IU Campus, We Have the Perfect Place for You. Contact Us Today!",
      "clickUrl": "pavprop.com",
      "cta": "Visit Site",
      "businessName": "Pavilion Properties",
      "address": "501 N Walnut St Ste 1B\nBloomington\n47404\nUS",
      "category": "Property management company",
      "imageUrls": ["https://lh3.googleusercontent.com/p/AF1QipMZOx-…"],
      "extensions": ["DIRECTIONS", "CALL"]
    }
  ]
}
```

Political ads additionally include:

```json
{
  "isPolitical": true,
  "spend": { "currency": "GBP", "lowerBound": 2500, "upperBound": 3000 },
  "impressions": { "lowerBound": 900000, "upperBound": 1000000 },
  "geoTargets": ["9046605", "9046664", "…"]
}
```

### 💰 Pricing

Pay only for what you use:

| Event | When it's charged |
|---|---|
| `ad` | Once per ad returned |
| `ocr-ad` | Only when text recovery actually runs on an image-only ad — never on ads with clean copy already available |
| `video-download` | Only if you turn on permanent video storage |

Leave text recovery and video storage off (the defaults) and you pay only the base price per ad.

### ❓ FAQ

**Do I need a proxy to scrape Google Ads?** Yes — a proxy is required and already configured by default, so most users don't need to change anything.

**Why is text recovery off by default?** Most ads — including most image-based product ads — already return clean, readable copy without it. Text recovery is reserved for the smaller set of ads that are genuinely image-only, so you're not paying for it on ads that don't need it.

**Will I get age-restricted ads?** No — those require a logged-in Google account to view and are out of scope for any Google Ads Transparency Center scraper that doesn't require you to log in.

**Is scraping Google Ads Transparency Center data legal?** This tool reads Google's own public ad-transparency data — the same information anyone can see by visiting adstransparency.google.com — without bypassing any login or verification step. You're responsible for how you use the output; check with your own counsel if you're unsure your use case is covered.

**How is this different from other Google Ads scrapers?** See "Why use this Google Ads Transparency Center scraper," above — political ad spend data, clean copy on far more ad types, no duplicate results, and downloadable video files are the biggest differences.

# Actor input Schema

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

A list of Google Ads Transparency Center URLs after a specific advertiser or domain is selected. Each URL must start with "https://adstransparency.google.com/..."

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

Plain advertiser names to resolve via SearchSuggestions instead of a pre-resolved Transparency Center URL. If several accounts share the name, all matching advertiser ids are queried at once.

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

Advertiser domains (e.g. "nike.com") to run a domain-scoped listing for, instead of a pre-resolved Transparency Center URL.

## `resultsLimit` (type: `integer`):

Maximum number of results per input URL/advertiser name/domain. Due to the concurrent nature of the actor, the actual number of requests may exceed the configured maximum.

## `skipDetails` (type: `boolean`):

If true, the actor will not open the details page for each individual ad. Instead, it will only scroll through the list of ads. All ads will be included, but the information for each ad may be less complete. Enabling this option results in much faster scraping.

## `topic` (type: `string`):

Restrict results to political ads (exposes spend and impressions data) or leave as all topics.

## `shouldDownloadAssets` (type: `boolean`):

Defines if the scraper should download creative assets (such as video ads) when the original URLs scraped have short expiry dates. This allows for more permanent storage of the files. Disclaimer: use this option with caution to avoid downloading excessive data from Google, which could be considered abusive. This option is ignored if "Skip details" is enabled.

## `shouldDownloadPreviews` (type: `boolean`):

Defines if the scraper should download creative previews as an HTML file, ensuring that the output field `previewUrl` is always populated. Enabling this option may slightly increase costs due to writes to a key-value store.

## `ocr` (type: `boolean`):

Enables local OCR (PaddleOCR, CPU-only) for screenshot-only ad variations (all IMAGE ads, plus the redundant screenshot of TEXT ads). Note: enabling OCR will significantly slow down the scraping speed and incurs a separate ocr-ad charge. This option is ignored if "Skip details" is enabled.

## `maxConcurrency` (type: `integer`):

Caps Crawlee's autoscaled pool. Leave unset to let Crawlee autoscale.

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

Select proxies to be used. A proxy is required — Google 429-blocks unproxied IPs after ~15-20 RPC calls.

## `assetProxyConfiguration` (type: `object`):

Optional separate proxy used only for downloading ad previews, images and videos. These are unthrottled CDN endpoints that account for roughly 90% of all traffic, so pointing them at a cheap flat-rate proxy moves the bulk of your bandwidth off metered residential proxy billing. Leave unset to download them through the main proxy, as before. If a download through this proxy fails, the scraper automatically retries via the main proxy, so results are never lost.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://adstransparency.google.com/advertiser/AR08888592736429539329?authuser=0&region=CH&preset-date=Last+30+days"
    }
  ],
  "skipDetails": false,
  "topic": "all",
  "shouldDownloadAssets": false,
  "shouldDownloadPreviews": false,
  "ocr": false,
  "proxyConfiguration": {
    "apifyProxyGroups": [],
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One structured record per scraped ad, including advertiser metadata and all fields available for the selected run mode.

# 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 = {
    "startUrls": [
        {
            "url": "https://adstransparency.google.com/advertiser/AR08888592736429539329?authuser=0&region=CH&preset-date=Last+30+days"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("api_creators/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 = { "startUrls": [{ "url": "https://adstransparency.google.com/advertiser/AR08888592736429539329?authuser=0&region=CH&preset-date=Last+30+days" }] }

# Run the Actor and wait for it to finish
run = client.actor("api_creators/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 '{
  "startUrls": [
    {
      "url": "https://adstransparency.google.com/advertiser/AR08888592736429539329?authuser=0&region=CH&preset-date=Last+30+days"
    }
  ]
}' |
apify call api_creators/google-ads-scraper --silent --output-dataset

```

## MCP server setup

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