# Google Ads Transparency Center Scraper (LatAm-ready) (`jgapis/google-ads-transparency-scraper`) Actor

Extract ads from the Google Ads Transparency Center by brand, advertiser ID or domain. Filter by country (CO, MX, BR, AR, CL, PE presets or any country), date range and format. Monitor mode returns only new ads. Optional full creative details, ad text, YouTube IDs and advertiser profiles. No login.

- **URL**: https://apify.com/jgapis/google-ads-transparency-scraper.md
- **Developed by:** [JG GOMEZ](https://apify.com/jgapis) (community)
- **Categories:** Lead generation, SEO tools
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 ad 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 Transparency Center Scraper (LatAm-ready)

Extract ads from the public [Google Ads Transparency Center](https://adstransparency.google.com) by **brand name, advertiser ID or domain**. You can filter by **country** (presets for Colombia, Mexico, Brazil, Argentina, Chile and Peru, or any other country), **date range** and **format** (text, image, video). **Monitor mode** returns only ads that are new since your last run. Optional **full creative details** add every variation, per-country dates, text-ad copy, YouTube video IDs and landing pages. You can also add **advertiser profiles** with verification status.

No login, no cookies, no browser. The Actor makes plain HTTP calls to the same public JSON endpoints the website uses, so it is fast and cheap.

> Independent tool, not affiliated with or endorsed by Google.

### Use cases

- **Competitor ad intelligence:** see every creative a competitor is running in your market, how long each one has been live, and which landing pages and UTM campaigns it uses.
- **Agencies in Latin America:** run daily monitors of clients' competitors in CO/MX/BR/AR/CL/PE and get only the new ads.
- **Creative research / swipe files:** collect image and video ads by brand or domain, with direct image URLs and YouTube links.
- **Brand protection:** find ads that point to your domain, or advertisers using your brand name.
- **Market research and journalism:** track advertising activity of banks, retailers, fintechs and political advertisers by country.

### Input

| Field | Type | Description |
|---|---|---|
| `searchTerms` | string\[] | Brand or advertiser names, e.g. `bancolombia`. Each term resolves to the matching advertiser(s) with the most ads. |
| `advertiserIds` | string\[] | Exact IDs such as `AR12885191334436012033` (taken from the advertiser URL). |
| `domains` | string\[] | Ads pointing to a domain, e.g. `liverpool.com.mx`. |
| `maxAdvertisersPerSearchTerm` | integer | How many matching advertisers to include per term (default 1). |
| `regions` | string\[] | ISO country codes (`CO`, `MX`, `BR`, `AR`, `CL`, `PE`, `US`, `ES`…), presets `LATAM_CORE` / `LATAM_ALL`, or empty / `anywhere`. |
| `startDate`, `endDate` | date | Only ads shown in this window (YYYY-MM-DD). Google serves date-filtered data for about the **last 12 months** only. |
| `format` | enum | `ALL`, `TEXT`, `IMAGE`, `VIDEO`. |
| `maxResults` | integer | Max ads per query (default 100). Results come newest first. |
| `includeDetails` | boolean | Adds all variations, per-country stats, text-ad copy, YouTube ID and landing page (charged per ad). |
| `extractAdText` | boolean | Used together with details: reads TEXT/VIDEO previews to get the headline, description, YouTube ID and landing page (default on). |
| `includeAdvertiserProfile` | boolean | Adds legal/verified name, country and verification status (charged once per advertiser). |
| `excludeLikelyIndividuals` | boolean | Drops advertisers whose name looks like a private person (see *Privacy*). |
| `monitorMode` | boolean | Outputs only ads not returned before for the same query and filters. |
| `monitorKey` | string | Optional label that keeps a separate monitor state (e.g. per client). |
| `proxyConfiguration` | object | Apify Proxy. Datacenter proxy is ON by default (recommended). |
| `residentialFallback` | boolean | Default `true`. If the datacenter proxy keeps getting blocked, switch to residential proxy automatically. |
| `maxConcurrency`, `requestsPerSecond`, `maxRetries` | integer | Politeness and robustness settings (defaults 4 / 1 / 6). |

Example:

```json
{
  "searchTerms": ["bancolombia"],
  "domains": ["liverpool.com.mx"],
  "regions": ["CO", "MX"],
  "format": "ALL",
  "maxResults": 200,
  "includeDetails": true,
  "includeAdvertiserProfile": true,
  "monitorMode": true
}
```

### Output

One dataset item per ad. Below is a real item from a test run on 2026-10-04 (query `bancolombia`, region `CO`, with details; long preview URLs shortened):

```json
{
  "adId": "CR17419182227702415361",
  "advertiserId": "AR12885191334436012033",
  "advertiserName": "Bancolombia SA",
  "format": "VIDEO",
  "firstShown": "2026-09-14T20:51:54Z",
  "lastShown": "2026-10-04T14:11:05Z",
  "daysShown": 21,
  "imageUrl": null,
  "previewUrl": "https://displayads-formats.googleusercontent.com/ads/preview/content.js?...",
  "adUrl": "https://adstransparency.google.com/advertiser/AR12885191334436012033/creative/CR17419182227702415361?region=CO",
  "advertiserLikelyIndividual": false,
  "advertiserIndividualReason": "contains business/legal-form keyword",
  "query": { "type": "searchTerm", "value": "bancolombia" },
  "regions": ["CO"],
  "details": {
    "format": "VIDEO",
    "variationsCount": 3,
    "variations": [{ "imageUrl": null, "previewUrl": "https://displayads-formats.googleusercontent.com/..." }],
    "regionStats": [{ "geoId": 2170, "countryCode": "CO", "lastShownDate": "2026-10-04" }],
    "youtubeVideoId": "qWRIt184UVI",
    "youtubeUrl": "https://www.youtube.com/watch?v=qWRIt184UVI",
    "headline": "Ábrela desde 0",
    "landingPageUrl": "bancolombia.com"
  },
  "advertiser": {
    "name": "Bancolombia SA", "legalName": "Bancolombia SA", "country": "CO", "isVerified": true,
    "profileUrl": "https://adstransparency.google.com/advertiser/AR12885191334436012033"
  },
  "scrapedAt": "2026-10-04T14:39:23Z"
}
```

Other fields you may see:

- Image and text ads: `imageUrl`, `width`, `height`.
- Text ads with an HTML preview: `details.adText` with `headline`, `displayUrl`, `description` and `sitelinks`.
- Some video ads: `details.videoFile`, a temporary signed MP4 URL.
- Monitor mode: `isNew` and `monitorFirstRun`.

Each run also writes a summary to the `OUTPUT` record of the default key-value store, with ads saved, per-query counts, the total ads Google reports and HTTP stats. Full samples are in `samples/`.

Dataset views: **Ads overview** (with creative thumbnails), **Details & ad text**, **Advertisers**.

### Pricing (pay per event)

| Event | Price |
|---|---|
| Run start | $0.005 per run |
| Ad result | **$1.00 per 1,000 ads** ($0.001 each) |
| Full creative detail (optional) | $0.002 per ad |
| Advertiser profile (optional) | $0.005 per unique advertiser per run |

Example: 1,000 ads with details and 3 advertiser profiles cost about $1.00 + $2.00 + $0.015 + $0.005 ≈ **$3.02**. In monitor mode you only pay for new ads. Set a **max cost per run** in Apify to cap spending; the Actor stops cleanly when the cap is reached.

### Tips and limitations

- **Date filter:** Google only returns date-filtered results for about the last 12 months. Older ranges come back empty.
- **Impression ranges and per-surface stats** are published by Google mainly for ads shown in the EU/EEA and Türkiye. For Latin America you usually get only first/last shown dates per country.
- **Text ads** are often archived by Google as images. In that case you get `imageUrl` but no `adText`.
- **Ad counts** reported by Google are ranges (e.g. 1,000–2,000), not exact numbers.
- **Rate limits:** Google throttles fast traffic from one IP (HTTP 429 or a CAPTCHA page). The Actor backs off and slows down automatically. Apify Proxy (datacenter) is enabled by default and the Actor automatically switches to residential proxy (a fresh IP per request) if Google keeps blocking, because runs without a proxy got throttled in our platform tests. Typical speed with full details: about 60 ads in 2–3 minutes; without details, hundreds of ads per minute.
- **Unofficial endpoints:** they are undocumented and may change. Field mappings were verified in October 2026.
- `surfaceId` values are Google's raw internal codes and are not mapped to names.

### Privacy

Advertisers in the Transparency Center are mostly businesses, but some are natural persons. Every ad carries `advertiserLikelyIndividual` and `advertiserIndividualReason`. This is a name-based heuristic (a common first name plus no business keywords), **not identity verification**. Turn on `excludeLikelyIndividuals` if you must avoid processing personal data (GDPR, LGPD, Colombian Ley 1581). Use the data responsibly and in line with the laws that apply to you and with Google's terms.

***

### 🇪🇸 En español

**¿Qué hace?** Extrae anuncios públicos del Centro de Transparencia de Anuncios de Google. Puedes buscar por **marca, ID de anunciante o dominio** y filtrar por **país** (atajos para Colombia, México, Brasil, Argentina, Chile y Perú, o cualquier país), **fechas** y **formato** (texto, imagen, video). No requiere login.

**Casos de uso**

- Espiar legalmente los anuncios de la competencia: creatividades, cuánto tiempo llevan activas, landing pages y campañas UTM.
- Agencias en LatAm: monitoreo diario de competidores con **modo monitor**, que entrega solo los anuncios nuevos.
- Bancos de ideas creativas (*swipe files*) de imágenes y videos, con enlaces directos a YouTube.
- Protección de marca: anuncios que apuntan a tu dominio o que usan tu nombre.

**Entrada:** `searchTerms` (p. ej. `bancolombia`), `advertiserIds`, `domains`, `regions` (`CO`, `MX`, `LATAM_CORE`…), `startDate`/`endDate`, `format`, `maxResults`, `includeDetails`, `includeAdvertiserProfile`, `excludeLikelyIndividuals`, `monitorMode`.

**Salida:** un registro por anuncio con ID, anunciante, formato, fechas de primera y última vez mostrado, días activo, imagen, enlace al Centro de Transparencia y, opcionalmente, variaciones, estadísticas por país, texto del anuncio, ID de YouTube, landing page y perfil verificado del anunciante. Hay un ejemplo real arriba y más en `samples/`.

**Precio (pago por evento):** $0,005 por ejecución, **$1,00 por cada 1.000 anuncios**, $0,002 por detalle completo y $0,005 por perfil de anunciante. En modo monitor solo pagas los anuncios nuevos.

**Limitaciones:** el filtro de fechas solo cubre aproximadamente los últimos 12 meses. Las impresiones solo se publican sobre todo para la UE. Si haces muchas consultas seguidas, Google puede limitar la IP; por eso Apify Proxy (datacenter) viene activado por defecto; no lo desactives.

**Privacidad:** cada anuncio indica si el anunciante *parece* una persona natural (`advertiserLikelyIndividual`). Activa `excludeLikelyIndividuals` para cumplir con la Ley 1581 de 2012, la LGPD o el RGPD.

# Actor input Schema

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

Brand or advertiser names, e.g. "bancolombia". Each term is resolved to the best-matching advertiser(s) in the Transparency Center (the ones with the most ads first).

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

Exact advertiser IDs (start with "AR"), copied from the advertiser URL, e.g. AR12885191334436012033.

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

Return ads that point to these domains, e.g. "liverpool.com.mx". Protocol, www. and paths are stripped automatically.

## `maxAdvertisersPerSearchTerm` (type: `integer`):

How many matching advertisers to include for each search term (sorted by number of ads).

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

ISO country codes (CO, MX, BR, AR, CL, PE, US, ES, ...) or presets LATAM_CORE (CO, MX, BR, AR, CL, PE) and LATAM_ALL (19 Latin American countries). Leave empty or use "anywhere" for all regions.

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

Only ads shown on or after this date (YYYY-MM-DD). The Transparency Center only serves date-filtered data for roughly the last 12 months. If only an end date is set, the start defaults to 30 days earlier.

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

Only ads shown on or before this date (YYYY-MM-DD). Defaults to today when a start date is set.

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

Filter by creative format.

## `maxResults` (type: `integer`):

Maximum number of ads to scan for each search term / advertiser ID / domain. Results come newest first (by last shown date).

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

Fetch every variation of each ad plus per-country first/last shown dates (and impression ranges where Google publishes them, mainly EU). Charged per ad as "Full creative detail".

## `extractAdText` (type: `boolean`):

Only used with full details. For TEXT and VIDEO ads, also reads the ad preview to get headline, display URL, description, sitelinks and the YouTube video ID (best effort, no extra charge).

## `includeAdvertiserProfile` (type: `boolean`):

Add the advertiser's verified/legal name, country and verification status. Fetched once per advertiser per run and charged once per advertiser.

## `excludeLikelyIndividuals` (type: `boolean`):

Every ad is flagged with advertiserLikelyIndividual (a name-based heuristic). Turn this on to drop those ads entirely, e.g. for GDPR / LGPD / Ley 1581 compliance.

## `monitorMode` (type: `boolean`):

Remembers ad IDs already returned for the same query + filters (in a named key-value store) and outputs only ads that are new since the previous run. The first run returns everything it scans. Ideal with Apify Schedules.

## `monitorKey` (type: `string`):

Optional label to keep separate monitoring states for the same query (e.g. per client).

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

Apify Proxy (datacenter) is ON by default: in platform tests, runs without a proxy were throttled by Google (HTTP 429 / CAPTCHA). Datacenter proxy is included in all Apify plans; switch to RESIDENTIAL only if you still see blocks.

## `residentialFallback` (type: `boolean`):

If Google keeps blocking the datacenter proxy (3 consecutive HTTP 429/CAPTCHA responses), automatically switch to Apify RESIDENTIAL proxy for the rest of the run. Ignored when no Apify Proxy is used.

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

Maximum number of requests in flight at once (details and previews are fetched in parallel).

## `requestsPerSecond` (type: `integer`):

Global rate limit (requests per second). Google blocks IPs that go too fast (HTTP 429 / CAPTCHA page); 1 req/s without proxy is a safe default. With Apify Proxy you can raise it.

## `maxRetries` (type: `integer`):

Retries with exponential backoff (2s, 4s, 8s... up to 90s) on network errors, HTTP 429 and 5xx. On 429 the whole Actor pauses and slows down automatically.

## Actor input object example

```json
{
  "searchTerms": [
    "bancolombia"
  ],
  "maxAdvertisersPerSearchTerm": 1,
  "regions": [
    "CO"
  ],
  "format": "ALL",
  "maxResults": 100,
  "includeDetails": false,
  "extractAdText": true,
  "includeAdvertiserProfile": false,
  "excludeLikelyIndividuals": false,
  "monitorMode": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true,
  "maxConcurrency": 4,
  "requestsPerSecond": 1,
  "maxRetries": 6
}
```

# Actor output Schema

## `overview` (type: `string`):

All scraped ads (overview view).

## `details` (type: `string`):

Ads with full creative details (headline, ad text, landing page, YouTube, per-country stats).

## `advertisers` (type: `string`):

Advertiser info per ad, including verification and the likely-individual flag.

## `runSummary` (type: `string`):

JSON summary: ads saved, new ads (monitor mode), details/profiles fetched, HTTP stats, per-query totals and errors.

# 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 = {
    "searchTerms": [
        "bancolombia"
    ],
    "regions": [
        "CO"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("jgapis/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 = {
    "searchTerms": ["bancolombia"],
    "regions": ["CO"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("jgapis/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 '{
  "searchTerms": [
    "bancolombia"
  ],
  "regions": [
    "CO"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call jgapis/google-ads-transparency-scraper --silent --output-dataset

```

## MCP server setup

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