# Google Ad Transparency Scraper (`axiomworks/google-ads-transparency-scraper`) Actor

Scrape public ad creative records from Google's Ads Transparency Center and return advertiser details, format, first and last shown dates, and available media URLs. Search by advertiser ID, name, or domain, filter by region and format, and optionally request numeric region details for each creative.

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

## Pricing

from $0.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.
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 Ad Transparency Scraper

Collect public creative records from Google's Ads Transparency Center. Search by advertiser ID, advertiser name, or domain and get structured records with creative identifiers, advertiser details, formats, display dates, and available media links. The Actor uses the public Transparency Center responses and does not require a Google login.

**Returns:** one row per ad creative with creativeId, advertiserId, advertiserName, format, firstShown, lastShown, daysActive, imageUrl, previewUrl, sourceUrl.
**Input:** `{"advertiserIds": ["AR16735076323512287233"], "region": "US", "maxItems": 20}` (also `domains` like nike.com, or `searchTerms` advertiser names)
**Best for:** competitor ad monitoring, ad creative research, advertiser lead lists.

```json
{"id": "CR11238584882709921793", "creativeId": "CR11238584882709921793", "advertiserId": "AR16735076323512287233", "advertiserName": "Nike, Inc.", "format": "text", "firstShown": "2023-11-16T22:30:36.000Z", "lastShown": "2026-10-01T19:22:17.000Z", "daysActive": 1051, "sourceUrl": "https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR11238584882709921793?region=US"}
```

### What does Google Ad Transparency Scraper do?

This Actor queries the public Google Ads Transparency Center for advertisements associated with an advertiser or domain. It turns the site's creative search response into one dataset row per creative. You can start with an `AR` advertiser ID, paste a Transparency Center advertiser URL, provide an advertiser name for suggestion matching, or search a domain. Multiple values can be combined in one run. A global `maxItems` limit caps the number of rows across all searches.

The Actor can filter by country and by creative format. The default region is the United States. Set `region` to `anywhere` when you want no regional restriction. The format filter accepts `all`, `text`, `image`, and `video`. Optional `shownFrom` and `shownTo` (YYYY-MM-DD) keep only ads whose display period overlaps that date range; they are applied after fetching, so narrow ranges scan more pages. If you enable details, the Actor makes an additional public request for each returned creative and includes numeric region codes supplied by Google. This takes longer than the basic search.

The source is Google's public Transparency Center, but this Actor is an independent tool. It is not affiliated with or endorsed by Google. The site's response structure can change. If it does, the Actor reports an error instead of inventing data. Results also depend on what the Transparency Center currently exposes for a particular advertiser, search term, domain, region, and format.

### What data can you get?

Each dataset row represents one creative. Fields that the public source does not supply are `null`. The overview view highlights the fields most useful for scanning a result set.

| Field | Meaning |
| --- | --- |
| `id` | Stable creative ID used to deduplicate rows within the run. |
| `creativeId` | Creative ID returned by the public search response. |
| `advertiserId` | Advertiser ID returned for the creative. |
| `advertiserName` | Advertiser name shown in the search result. |
| `format` | Creative format: text, image, or video when identified. |
| `firstShown` | First display timestamp in ISO date format. |
| `lastShown` | Last display timestamp in ISO date format. |
| `daysActive` | Inclusive days between `firstShown` and `lastShown`; null if either is missing. |
| `imageUrl` | Archive image URL when an image tag is present in the response. |
| `previewUrl` | Creative preview URL when Google provides one. |
| `domain` | Domain used to find the record on a domain search. |
| `regions` | Numeric region codes from the optional detail request. |
| `regionCodes` | ISO country codes (for example US) mapped from `regions` when `includeDetails` is on. |
| `sourceUrl` | Transparency Center page for the creative. |

The image URL and preview URL are references to media or preview content; this Actor does not download or render the asset. A text format creative can still have an image URL because the source represents some rendered text ads as archived images. `firstShown` and `lastShown` are converted from the source's Unix timestamps. An active ad may have a recent `lastShown` value. The domain field identifies the search input that found a row and is not a claim that the advertiser owns that domain.

### How to use

Open the Actor input form and enter at least one advertiser ID, advertiser name, or domain. For the most precise search, use an advertiser ID from a public Transparency Center advertiser page. If you use an advertiser name, the Actor requests Google's search suggestions and selects an exact case insensitive match when available; otherwise it uses the first advertiser suggestion. Review the returned `advertiserId` and `advertiserName` when a name could refer to several entities.

Choose a country code such as `US` if the geographic scope matters. Select `anywhere` to omit the regional filter. Choose a format or keep `all`. Set `maxItems` to the largest number of unique creative rows you want. The Actor paginates while a next page token exists and stops once it has pushed that many rows. If multiple searches find the same creative, the Actor emits it once.

Enable `includeDetails` when numeric region codes are useful. This makes a detail request for each selected creative and may expose an additional preview link. Detail failures are reported in the log; the search record is still returned. Apify datacenter proxy is enabled by default because Google rate limits direct requests. Blocked requests are retried with backoff and a fresh proxy session.

A search with no matching creatives, an unresolved name, or a target that stays blocked completes (SUCCEEDED) with an empty dataset and a status message saying what to change. An invalid region, missing target, or changed response structure produces a clear error. The Actor never puts error messages or placeholder rows in the dataset. For reproducible downstream processing, rely on the field names in the table and allow nullable values.

### Input

| Field | Input | Default and behavior |
| --- | --- | --- |
| `advertiserIds` | Array of `AR` IDs or advertiser page URLs | Optional search target. |
| `searchTerms` | Array of advertiser names | Optional search target resolved through suggestions. |
| `domains` | Array of domain names | Optional search target for domain matching. |
| `region` | Two letter country code or `anywhere` | `US`. |
| `format` | `all`, `text`, `image`, or `video` | `all`. |
| `maxItems` | Integer from 1 to 10000 | `50` unique rows across the run. |
| `shownFrom` | Date `YYYY-MM-DD` | Optional; skip ads that stopped running before this date. |
| `shownTo` | Date `YYYY-MM-DD` | Optional; skip ads first shown after this date. |
| `includeDetails` | Boolean | `false`; request per creative details when true. |
| `proxyConfiguration` | Apify Proxy settings | Apify Proxy enabled by default; keep it on. |

Supply at least one value in the first three arrays. The form shows example values as prefills; API callers should send their own targets. A page URL in `advertiserIds` must contain an `AR` identifier. Invalid identifiers are warned about and skipped. The `region` field accepts supported country codes from the Actor's region table. If a requested code is unsupported, use `anywhere` or choose another supported code.

```json
{
  "advertiserIds": ["AR16735076323512287233"],
  "region": "US",
  "format": "all",
  "maxItems": 20,
  "includeDetails": false,
  "proxyConfiguration": {"useApifyProxy": true}
}
```

For a domain search, send `{"domains":["nike.com"],"region":"US","format":"text","maxItems":40}`. For a name search, send `{"searchTerms":["Nike"],"maxItems":20}`. Name matching can be ambiguous, so the returned advertiser fields should be checked before treating a run as belonging to a specific company.

### Output

The example below is based on the Architect's live probe of the public creative search response. The exact set of live ads and display dates changes over time. Nullable fields are shown explicitly so you can see the record shape used by the dataset.

```json
{
  "id": "CR11238584882709921793",
  "creativeId": "CR11238584882709921793",
  "advertiserId": "AR16735076323512287233",
  "advertiserName": "Nike, Inc.",
  "format": "text",
  "firstShown": "2023-11-16T22:30:36.000Z",
  "lastShown": "2026-10-01T19:22:17.000Z",
  "daysActive": 1051,
  "imageUrl": "https://tpc.googlesyndication.com/archive/simgad/10395020757433762867",
  "previewUrl": null,
  "domain": null,
  "regions": null,
  "regionCodes": null,
  "sourceUrl": "https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR11238584882709921793?region=US"
}
```

When `includeDetails` is enabled, `regions` can contain numeric country identifiers returned by the detail service. A preview URL can be present for creatives that have a hosted preview. Different formats expose different media references. The Actor preserves the creative and advertiser IDs as strings so their leading digits and full precision remain intact.

### How much does it cost?

This Actor is charged per result pushed to the dataset. One unique creative row is one `result` event. A duplicate creative found on a later page or in another search does not produce a second row. `maxItems` sets the maximum number of rows and therefore the maximum number of result events in a run. See the Actor's Pricing tab for the current terms. Proxy usage and other platform resources, if selected, are governed by your Apify account settings.

### Use with AI agents (MCP)

Apify's MCP server can expose this Actor as a tool. Add the server URL below to an MCP client that supports remote servers, then enable the Actor tool. The exact client configuration interface varies by client.

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=axiomworks/google-ads-transparency-scraper"
    }
  }
}
```

Example prompts include “Find recent public creatives for advertiser ID AR16735076323512287233 in the US and return ten records,” “Search ads associated with nike.com and show the text format creative IDs and display dates,” and “Get public creative previews for this advertiser and include available region codes.” An agent should provide a target in its tool call because form prefills do not populate API calls. It should also read nullable fields as missing source data, not as proof that a media asset or region does not exist.

The structured dataset makes it possible to compare creatives across advertiser searches, organize research by last shown date, and save a set of source page URLs for review. A downstream agent can cite `sourceUrl` for a row. The MCP tool returns public records from the Actor's run; it cannot access private account data or ads hidden behind a login.

### Integrations and API

Use Apify datasets to connect results to your own analysis. The examples below start the Actor with an explicit input and then read dataset items. Set the Apify API token in your environment or SDK configuration using your normal private setup. Do not place a token in a shared document or repository.

Python using the Apify client:

```python
from apify_client import ApifyClient
import os
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("axiomworks/google-ads-transparency-scraper").call(run_input={
    "advertiserIds": ["AR16735076323512287233"], "maxItems": 10
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["creativeId"], item["sourceUrl"])
```

JavaScript using the Apify client:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('axiomworks/google-ads-transparency-scraper').call({
  advertiserIds: ['AR16735076323512287233'], maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) process.stdout.write(`${item.creativeId} ${item.sourceUrl}\n`);
```

cURL to start a run uses the same JSON input:

```bash
curl -X POST 'https://api.apify.com/v2/acts/axiomworks~google-ads-transparency-scraper/runs' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"advertiserIds":["AR16735076323512287233"],"maxItems":10}'
```

The run response contains a dataset identifier. Retrieve its items through the Apify dataset API after the run finishes. If you need a fixed snapshot for analysis, save the dataset associated with that run rather than rerunning a live search and expecting the same advertisements or dates.

### FAQ

**How are duplicate ads handled?** The Actor uses the creative ID as the stable row ID and emits that ID once per run. Duplicates across pages and search inputs are skipped. The first search that finds an ID determines its `domain` field.

**Can I pass a public advertiser page URL?** Yes. The Actor extracts its `AR` identifier and searches that advertiser. Other URL content is not fetched or used as an alternate source.

**Why is a media URL null?** The search response does not always include an archived image or hosted preview. Media references depend on creative type and the fields Google exposes for the record. The Actor does not guess a URL.

**Does a name search always find the intended advertiser?** No. Google can return multiple suggestions. The Actor favors an exact case insensitive name match and otherwise uses the first advertiser suggestion. Search by ID when precision matters.

**What happens when the site blocks a request?** The Actor retries blocked or rate limited responses with backoff. When Apify Proxy is selected, retry attempts use fresh sessions. A target that cannot recover ends the run with zero rows and a status message, so the dataset is not silently filled with fabricated records.

**Why did a search return no rows?** The target may have no visible creatives under the chosen region and format, the domain may not match a creative, or an advertiser name may not resolve. Try an advertiser ID, use `anywhere`, or select `all` formats and review the warning log.

### Is it legal to scrape Google?

The Actor accesses public Transparency Center data without a login. Legal rules and site terms vary by location and use case. Evaluate your intended collection, storage, and redistribution against applicable requirements. Be considerate of the source and use modest request volumes. This Actor is independent of Google and provides source URLs so you can inspect the original public records.

### Feedback

If a field looks wrong, include the run ID, the `sourceUrl`, the input used, and the affected field in a report through the Actor's Apify Store feedback channel. That gives a maintainer enough context to compare the dataset row with the live public response. Please avoid putting private account information or credentials in feedback. A change to Google's internal response format may require a parser update; a clear example helps locate it.

# Actor input Schema

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

Google advertiser IDs starting with AR, or advertiser page URLs from adstransparency.google.com, e.g. \["AR16735076323512287233"]. Most precise target. Provide at least one of advertiserIds, searchTerms or domains; they can be combined.

## `searchTerms` (type: `array`):

Advertiser names to look up, e.g. \["Nike"]. Each name resolves to the closest advertiser via Google suggestions (exact name match preferred), so check advertiserName in results; use advertiserIds when precision matters.

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

Website domains to find ads for, e.g. \["nike.com"]. Bare domain without https:// or paths. Returns ads whose creatives match that domain.

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

Two-letter ISO country code the ads were shown in, e.g. "US", "GB", "DE", "FR", "JP", "BR", or "anywhere" for no country filter. Default "US". Unsupported codes fail the run immediately.

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

Only return this ad format: "all" (default), "text", "image" or "video". Filtered after fetching, so a rare format scans more pages.

## `shownFrom` (type: `string`):

Only ads still running on or after this date, format YYYY-MM-DD, e.g. "2025-01-01". Filtered after fetching, so narrow ranges scan more pages. Leave empty for no limit.

## `shownTo` (type: `string`):

Only ads first shown on or before this date, format YYYY-MM-DD, e.g. "2025-06-30". Leave empty for no limit.

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

Maximum number of unique ads to return across all targets, integer 1-10000, e.g. 20. Default 50.

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

true to make one extra request per ad and fill regions (numeric codes) and regionCodes (ISO countries where it ran), e.g. \["US","CA"]. Slower. Default false.

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

Apify Proxy settings, e.g. {"useApifyProxy": true}. Keep enabled: Google rate limits direct requests. Default datacenter proxy.

## Actor input object example

```json
{
  "advertiserIds": [
    "AR16735076323512287233"
  ],
  "region": "US",
  "format": "all",
  "maxItems": 20,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# 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"
    ],
    "region": "US",
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/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 = {
    "advertiserIds": ["AR16735076323512287233"],
    "region": "US",
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/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 '{
  "advertiserIds": [
    "AR16735076323512287233"
  ],
  "region": "US",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call axiomworks/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

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