# Google Ads scraper (`lentic_clockss/google-ads-transparency-center-vn`) Actor

Google Ads Scraper extracts structured ad data from the Google Ads Transparency Center for advertiser and domain searches. It returns advertiser names, creative IDs, ad formats, first/last seen dates, detail URLs, and preview links for competitor research, ad monitoring, and market analysis.

- **URL**: https://apify.com/lentic\_clockss/google-ads-transparency-center-vn.md
- **Developed by:** [kane liu](https://apify.com/lentic_clockss) (community)
- **Categories:** Developer tools, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 result items

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Transparency Center Scraper

Scrape Google Ads Transparency Center creatives from Apify by **advertiser** or **domain**.

This Actor is intentionally narrow and honest:

- it supports only `advertiser` and `domain` targets;
- it is **VN-first** in its published schema and verified smoke coverage;
- it returns stable search-level fields first, then adds **best-effort** preview/detail enrichment;
- it does **not** claim production-hardening against every Google anti-bot, region, or ad-format variant.

If you need a Store-facing summary in one sentence: this Actor is useful today for **Google Ads Transparency Center lookup workflows where stable creative IDs, advertiser names, preview URLs, and basic preview-derived fields are enough, and deeper enrichment is treated as opportunistic**.

### What this Actor is good for

Use it when you want to:

- collect creatives for a known **advertiser** in Google Ads Transparency Center;
- collect creatives for a known **domain**;
- monitor stable identifiers such as `advertiserId`, `advertiserName`, `creativeId`, `detailUrl`, and `formatCode`;
- keep the original creative/detail payload when available via `rawCreativeJson` / `rawAdvertiserJson`;
- extract lightweight preview content such as `headline`, `channelName`, `destinationUrl`, or `visibleUrl` when the preview parser can resolve them.

### What it does not promise

This repository should **not** be read as a claim that:

- all countries are equally verified or equally stable;
- all ad formats yield the same structured preview fields;
- `GetCreativeById` always returns a useful payload;
- advertiser-name suggestion resolution is fully production-verified;
- proxies, retries, browser warmup, and anti-bot handling are already production-grade.

### Current real capability, without hype

#### Supported search modes

- `advertiser`
- `domain`

#### Region scope

- Input validation accepts any two-letter country code.
- The live client currently contains region-to-collection mappings for: `AU`, `BR`, `CA`, `DE`, `FR`, `GB`, `IN`, `JP`, `PH`, `SG`, `US`, `VN`.
- **Published positioning and verified smoke coverage remain VN-centered.** The current Store-facing schema and validation artifacts are still tuned to the VN-verified path, so this Actor should still be presented as a **VN-validated MVP**, not as a fully verified global scraper.

#### Important implementation limits

These are real current limits of the codebase:

- `targets` is an array in the input schema, but the current runtime processes **only the first target** per run.
- `includeCreativeDetails=true` is best-effort. The field exists, the lookup is wired, but the returned payload quality is not uniform.
- `includeVariantContent=true` is best-effort. Some previews yield good headline/url extraction; others only expose partial text or nothing structured.
- `includeRawJson=true` does **not** currently populate every raw field uniformly:
  - `rawCreativeJson` can be populated when `GetCreativeById` returns a payload;
  - `rawAdvertiserJson` can be populated when advertiser lookup runs and succeeds;
  - `rawSearchCreativesJson` is present in the schema but is currently written as `null` by the implementation.

### Verified status

#### Verified locally in deterministic fixture mode

The fixture path is the most reliable, closed-loop validation path in this repo.

It is locally validated to:

- parse fixture `SearchCreatives` responses;
- optionally merge fixture `GetCreativeById` payloads;
- optionally parse fixture variant content;
- write dataset items to Apify local storage;
- write `RUN_SUMMARY`.

#### Verified in real mode

There are two different truths to keep separate:

1. **This repository contains prior successful real advertiser artifacts** for:
   - `region=VN`
   - `searchMode=advertiser`
   - `searchValue=AR16735076323512287233`
2. **The current local rerun in this environment is not guaranteed to pass every time.** On this machine, the latest live smoke attempt hit Google rate limiting (`429 Too Many Requests`), so live mode must still be treated as fragile.

Beyond the default advertiser smoke, repository notes also record one manually verified domain path:

- `region=VN`
- `searchMode=domain`
- `searchValue=chatgpt.com`

#### `GetCreativeById` / `rawCreativeJson` status

The old README text saying live `GetCreativeById` basically returns `{}` is now too absolute.

The accurate boundary is:

- the Actor already stores `rawCreativeJson` when `GetCreativeById` returns something usable;
- recent repository-local advertiser artifacts still show cases where `rawCreativeJson` is `{}`;
- separately verified remote advertiser runs have already shown **non-empty** `rawCreativeJson`;
- therefore `GetCreativeById` is **real but unstable**, and `rawCreativeJson` should be treated as **opportunistic enrichment, not a guaranteed output field**.

#### Preview enrichment status

The current main enrichment path is:

- `SearchCreatives` search rows, plus
- preview `content.js` fetching/parsing, plus
- inline preview HTML parsing when the row does not expose a `previewUrl`.

What is genuinely verified here:

- search-level fields are the most stable output layer;
- `previewUrl` can be present and useful, but it is nullable;
- inline preview HTML can supply enrichment when `previewUrl` is absent;
- some live preview payloads yield useful fields like `headline`, `channelName`, `destinationUrl`, and `visibleUrl`.

What is **not** guaranteed:

- every ad format exposes a preview payload the current parser understands;
- every preview will yield `headline` or `description`;
- preview parsing is stable across all regions and format families.

### Input contract

This section documents the current input contract as implemented by `input_schema.json` and the runtime.

### Input

Top-level input fields supported by `input_schema.json`:

| Field | Type | Notes |
|---|---|---|
| `runMode` | `fixture` \| `real` | `fixture` is deterministic and fully testable; `real` hits live Google endpoints. |
| `region` | string | Defaults to `VN`. Any two-letter code passes input validation, but verified/store-safe positioning remains VN-first. |
| `targets` | array | Required. **Current runtime only processes the first target item.** |
| `maxCreativesPerTarget` | integer | 1-100. |
| `includeCreativeDetails` | boolean | Enables best-effort `GetCreativeById` lookup. |
| `includeVariantContent` | boolean | Enables best-effort preview/variant parsing. |
| `includeRawJson` | boolean | Keeps raw detail payloads when actually fetched/successful. |
| `fixtures` | object | Optional in `fixture` mode. If omitted, the Actor auto-loads its built-in deterministic smoke fixtures. |
| `proxyConfiguration` | object | Apify proxy editor-compatible config. |
| `session` | object | Optional cookies/headers/user agent for live mode. |
| `rpcIds` | object | Listed in schema for overrides, but the live runtime currently uses `rpcPaths` internally. Treat as advanced/internal. |
| `baseUrl` | string | Defaults to `https://adstransparency.google.com`. |
| `requestTimeoutSecs` | number | Defaults to 30. |
| `debug` | boolean | Extra logging. |
| `keepDebugArtifacts` | boolean | Keep intermediate artifacts. |

#### Target object

```json
{
  "searchMode": "domain",
  "searchValue": "example.com",
  "targetLabel": "Example domain"
}
````

Notes:

- `searchMode` must be `domain` or `advertiser`.
- `searchValue` must be a non-empty string.
- For advertiser runs, the most reliable input is a known advertiser ID such as `AR16735076323512287233`.
- The client also contains advertiser-suggestion resolution for non-ID advertiser queries, but that path is **not** the primary verified smoke path.

### Example inputs

#### 1) Fixture mode

```json
{
  "runMode": "fixture",
  "region": "VN",
  "targets": [
    {
      "searchMode": "domain",
      "searchValue": "example.com",
      "targetLabel": "Fixture smoke"
    }
  ],
  "maxCreativesPerTarget": 2,
  "includeCreativeDetails": true,
  "includeVariantContent": true,
  "fixtures": {
    "searchCreatives": "fixtures/rpc/search_creatives_domain_vn.json",
    "creativeById": {
      "crt-900": "fixtures/rpc/get_creative_by_id_crt-900.json",
      "crt-901": "fixtures/rpc/get_creative_by_id_crt-901.json"
    },
    "advertiserById": {
      "adv-100": "fixtures/rpc/get_advertiser_by_id_adv-100.json",
      "adv-101": "fixtures/rpc/get_advertiser_by_id_adv-101.json"
    }
  }
}
```

#### 2) Real advertiser smoke

```json
{
  "runMode": "real",
  "region": "VN",
  "maxCreativesPerTarget": 1,
  "targets": [
    {
      "searchMode": "advertiser",
      "searchValue": "AR16735076323512287233",
      "targetLabel": "Nike live advertiser smoke"
    }
  ],
  "includeCreativeDetails": true,
  "includeVariantContent": true
}
```

#### 3) Real domain smoke

```json
{
  "runMode": "real",
  "region": "VN",
  "maxCreativesPerTarget": 2,
  "targets": [
    {
      "searchMode": "domain",
      "searchValue": "chatgpt.com",
      "targetLabel": "ChatGPT live domain smoke"
    }
  ],
  "includeCreativeDetails": true,
  "includeVariantContent": true
}
```

### Output contract

This section documents the current published dataset contract and the known schema/runtime nuances.

### Output

The published dataset model is defined in `.actor/dataset_schema.json`.

#### Stable output fields

These are the most dependable fields in current practice:

- `runId`
- `region`
- `searchMode`
- `searchValue`
- `advertiserId`
- `advertiserName`
- `creativeId`
- `detailUrl`
- `previewUrl` (required key, nullable value)
- `formatCode`
- `scrapedAt`

#### Best-effort enrichment fields

These may be present, null, partial, or format-dependent:

- `firstShownRaw`
- `lastShownRaw`
- `resultCountLower`
- `resultCountUpper`
- `variantCount`
- `headline`
- `description`
- `destinationUrl`
- `visibleUrl`
- `redirectUrl`
- `videoId`
- `channelName`
- `channelIcon`
- `rawCreativeJson`
- `rawAdvertiserJson`
- `variantParseSource`
- `warnings`

#### Known schema/implementation nuance

- `rawSearchCreativesJson` exists in the dataset schema but is currently emitted as `null` by the code.

### Example output

This example is based on a real advertiser artifact already present in `artifacts/`:

```json
{
  "runId": "local-run",
  "region": "VN",
  "searchMode": "advertiser",
  "searchValue": "AR16735076323512287233",
  "targetLabel": "Nike live advertiser smoke",
  "advertiserId": "AR16735076323512287233",
  "advertiserName": "Nike, Inc.",
  "creativeId": "CR01003845904182018049",
  "detailUrl": "https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR01003845904182018049",
  "previewUrl": "https://displayads-formats.googleusercontent.com/ads/preview/content.js?...",
  "formatCode": 2,
  "headline": "FC Barcelona Academy Pro Home Nike Men's Dri-FIT Soccer Pre-Match Short-Sleeve Top in Blue, Size: Large | HJ7142-456",
  "channelName": "Nike",
  "rawCreativeJson": {},
  "variantParseSource": "https://displayads-formats.googleusercontent.com/ads/preview/content.js?...",
  "warnings": []
}
```

That example shows the right interpretation of current output quality:

- search-level fields are solid;
- preview-derived `headline` may be available;
- `rawCreativeJson` may still be `{}` even in a successful live run.

### Project layout

```text
.actor/
  actor.json
  dataset_schema.json
fixtures/
  rpc/
  smoke/
src/
  parsers/
  google_ads_client.py
  http_client.py
  input_model.py
  main.py
  normalizers.py
  runtime.py
  storage.py
tests/
README.md
input_schema.json
```

### Local validation

The repository ships with explicit validation scripts.

Recommended commands:

```bash
python3 -m pytest -q
python3 apify_actor_static_audit.py --repo-root . --config static_audit_config.json
python3 apify_actor_dynamic_test.py --repo-root . --config dynamic_test_config.json
python3 apify_actor_quality_gate.py --repo-root . --config quality_gate_config.json
python3 apify_actor_dynamic_test.py --repo-root . --config dynamic_test_real_config.json
```

What those checks mean:

- `pytest -q`: unit/integration coverage around the parser/runtime layer.
- `static_audit`: required files and metadata exist.
- `dynamic_test_config.json`: fixture-mode closed loop must write dataset + `RUN_SUMMARY`.
- `quality_gate`: validates the fixture dataset against expected quality requirements.
- `dynamic_test_real_config.json`: live smoke against the current real advertiser path. This is useful, but may fail due to rate limiting or anti-bot behavior.

### Troubleshooting

#### Live run fails with HTTP 429

This is currently the most important real-world failure mode.

What it means:

- Google rate-limited the request path;
- the Actor is not yet robust enough to guarantee success without better session/proxy handling.

What to try:

- use Apify residential proxy settings in `proxyConfiguration`;
- provide better session cookies / headers / user agent in `session`;
- reduce request frequency and rerun later;
- keep `maxCreativesPerTarget` low for smoke runs.

#### `previewUrl` is null

This can be valid.

Some search rows expose inline preview HTML instead of a separate preview URL. Treat `previewUrl` as nullable and inspect:

- `headline`
- `destinationUrl`
- `visibleUrl`
- `variantParseSource`
- `warnings`

#### `rawCreativeJson` is `{}` or null

This does not automatically mean the run failed.

Interpretation:

- the search path still may have succeeded;
- preview enrichment still may have succeeded;
- `GetCreativeById` simply did not return a richer payload in that run.

#### `advertiserName` is missing or advertiser raw payload is null

Advertiser lookup is currently secondary to search-row output. If Google blocks or returns sparse advertiser-detail payloads, the Actor falls back to row-level fields when possible.

### Store-positioning summary

If you publish this on Apify Store, the accurate positioning is:

- a **Google Ads Transparency Center scraper**;
- focused on **advertiser/domain lookups**;
- **VN-validated MVP** with fixture-backed tests and a real advertiser smoke path;
- useful stable metadata extraction plus **best-effort** preview/detail enrichment;
- not yet a claim of globally stable, production-hardened scraping across all regions and formats.

# Actor input Schema

## `runMode` (type: `string`):

Choose fixture mode for the deterministic smoke path or real mode for live Google Ads Transparency Center requests.

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

Two-letter country code used for Google Ads Transparency Center region targeting. Defaults to VN but supports multi-region inputs such as US, DE, JP, and SG.

## `targets` (type: `array`):

One or more Transparency Center targets. Stage one only supports domain and advertiser searches.

## `maxCreativesPerTarget` (type: `integer`):

Upper bound for creatives emitted per target.

## `includeCreativeDetails` (type: `boolean`):

When true, fetch and merge GetCreativeById detail payloads.

## `includeVariantContent` (type: `boolean`):

When true, fetch and parse variant content payloads.

## `includeRawJson` (type: `boolean`):

When true, preserve raw RPC payload fragments in nullable dataset fields.

## `fixtures` (type: `object`):

Optional in fixture mode. When omitted, the Actor auto-loads its built-in deterministic smoke fixtures.

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

Official Apify proxy input. Prefer useApifyProxy/apifyProxyGroups/apifyProxyCountry for Apify residential routing; proxyUrls is kept for custom proxies.

## `session` (type: `object`):

Optional live-mode session material such as cookies, headers, and user agent.

## `rpcIds` (type: `object`):

Optional rpcids overrides for search\_creatives, get\_creative\_by\_id, and get\_advertiser\_by\_id.

## `baseUrl` (type: `string`):

Optional override for the Transparency Center origin. Leave empty for production.

## `requestTimeoutSecs` (type: `number`):

HTTP timeout for live-mode requests.

## `debug` (type: `boolean`):

Enable extra debug logging for local and remote troubleshooting.

## `keepDebugArtifacts` (type: `boolean`):

Keep intermediate artifacts instead of cleaning them after the run.

## Actor input object example

```json
{
  "runMode": "fixture",
  "region": "VN",
  "targets": [
    {
      "searchMode": "domain",
      "searchValue": "example.com",
      "targetLabel": "Example domain"
    }
  ],
  "maxCreativesPerTarget": 30,
  "includeCreativeDetails": true,
  "includeVariantContent": true,
  "includeRawJson": false,
  "fixtures": {
    "searchCreatives": "fixtures/rpc/search_creatives_domain_vn.json",
    "creativeById": {
      "crt-900": "fixtures/rpc/get_creative_by_id_crt-900.json",
      "crt-901": "fixtures/rpc/get_creative_by_id_crt-901.json"
    },
    "advertiserById": {
      "adv-100": "fixtures/rpc/get_advertiser_by_id_adv-100.json",
      "adv-101": "fixtures/rpc/get_advertiser_by_id_adv-101.json"
    }
  },
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "baseUrl": "https://adstransparency.google.com",
  "requestTimeoutSecs": 30,
  "debug": false,
  "keepDebugArtifacts": false
}
```

# Actor output Schema

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

Creative-level results stored in the default dataset.

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

Structured JSON summary stored under the RUN\_SUMMARY key in the default key-value store.

## `runSummaryCollection` (type: `string`):

Filtered key list for schema-defined output records in the default key-value store.

# 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 = {
    "targets": [
        {
            "searchMode": "domain",
            "searchValue": "example.com",
            "targetLabel": "Example domain"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lentic_clockss/google-ads-transparency-center-vn").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 = { "targets": [{
            "searchMode": "domain",
            "searchValue": "example.com",
            "targetLabel": "Example domain",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("lentic_clockss/google-ads-transparency-center-vn").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "targets": [
    {
      "searchMode": "domain",
      "searchValue": "example.com",
      "targetLabel": "Example domain"
    }
  ]
}' |
apify call lentic_clockss/google-ads-transparency-center-vn --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=lentic_clockss/google-ads-transparency-center-vn",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Ads scraper",
        "description": "Google Ads Scraper extracts structured ad data from the Google Ads Transparency Center for advertiser and domain searches. It returns advertiser names, creative IDs, ad formats, first/last seen dates, detail URLs, and preview links for competitor research, ad monitoring, and market analysis.",
        "version": "0.1",
        "x-build-id": "Xvpmgt071BAP9GnMT"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/lentic_clockss~google-ads-transparency-center-vn/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-lentic_clockss-google-ads-transparency-center-vn",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/lentic_clockss~google-ads-transparency-center-vn/runs": {
            "post": {
                "operationId": "runs-sync-lentic_clockss-google-ads-transparency-center-vn",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/lentic_clockss~google-ads-transparency-center-vn/run-sync": {
            "post": {
                "operationId": "run-sync-lentic_clockss-google-ads-transparency-center-vn",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "targets"
                ],
                "properties": {
                    "runMode": {
                        "title": "Run mode",
                        "enum": [
                            "fixture",
                            "real"
                        ],
                        "type": "string",
                        "description": "Choose fixture mode for the deterministic smoke path or real mode for live Google Ads Transparency Center requests.",
                        "default": "fixture"
                    },
                    "region": {
                        "title": "Region",
                        "pattern": "^[A-Za-z]{2}$",
                        "type": "string",
                        "description": "Two-letter country code used for Google Ads Transparency Center region targeting. Defaults to VN but supports multi-region inputs such as US, DE, JP, and SG.",
                        "default": "VN"
                    },
                    "targets": {
                        "title": "Targets",
                        "minItems": 1,
                        "type": "array",
                        "description": "One or more Transparency Center targets. Stage one only supports domain and advertiser searches.",
                        "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                                "searchMode",
                                "searchValue"
                            ],
                            "properties": {
                                "searchMode": {
                                    "title": "Search mode",
                                    "type": "string",
                                    "description": "Only domain and advertiser targets are supported in stage one.",
                                    "enum": [
                                        "domain",
                                        "advertiser"
                                    ]
                                },
                                "searchValue": {
                                    "title": "Search value",
                                    "type": "string",
                                    "description": "The domain or advertiser value sent to Transparency Center.",
                                    "minLength": 1
                                },
                                "targetLabel": {
                                    "title": "Target label",
                                    "type": "string",
                                    "description": "Optional reporting label for grouping output rows."
                                }
                            }
                        }
                    },
                    "maxCreativesPerTarget": {
                        "title": "Max creatives per target",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Upper bound for creatives emitted per target.",
                        "default": 30
                    },
                    "includeCreativeDetails": {
                        "title": "Include creative details",
                        "type": "boolean",
                        "description": "When true, fetch and merge GetCreativeById detail payloads.",
                        "default": true
                    },
                    "includeVariantContent": {
                        "title": "Include variant content",
                        "type": "boolean",
                        "description": "When true, fetch and parse variant content payloads.",
                        "default": true
                    },
                    "includeRawJson": {
                        "title": "Include raw JSON",
                        "type": "boolean",
                        "description": "When true, preserve raw RPC payload fragments in nullable dataset fields.",
                        "default": false
                    },
                    "fixtures": {
                        "title": "Fixture bundle",
                        "type": "object",
                        "description": "Optional in fixture mode. When omitted, the Actor auto-loads its built-in deterministic smoke fixtures.",
                        "default": {
                            "searchCreatives": "fixtures/rpc/search_creatives_domain_vn.json",
                            "creativeById": {
                                "crt-900": "fixtures/rpc/get_creative_by_id_crt-900.json",
                                "crt-901": "fixtures/rpc/get_creative_by_id_crt-901.json"
                            },
                            "advertiserById": {
                                "adv-100": "fixtures/rpc/get_advertiser_by_id_adv-100.json",
                                "adv-101": "fixtures/rpc/get_advertiser_by_id_adv-101.json"
                            }
                        }
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Official Apify proxy input. Prefer useApifyProxy/apifyProxyGroups/apifyProxyCountry for Apify residential routing; proxyUrls is kept for custom proxies.",
                        "properties": {
                            "useApifyProxy": {
                                "title": "Use Apify Proxy",
                                "type": "boolean",
                                "description": "When true, use Apify Proxy instead of custom proxy URLs."
                            },
                            "apifyProxyGroups": {
                                "title": "Apify Proxy groups",
                                "description": "Optional Apify Proxy groups such as RESIDENTIAL.",
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            },
                            "proxyUrls": {
                                "title": "Custom proxy URLs",
                                "description": "Optional custom proxy URLs. For Apify residential routing inside Actors, prefer useApifyProxy + apifyProxyGroups + apifyProxyCountry instead of passing Apify proxy URLs manually.",
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            },
                            "apifyProxyCountry": {
                                "title": "Apify Proxy country",
                                "description": "Two-letter country code for Apify Proxy geo targeting.",
                                "type": "string",
                                "pattern": "^[A-Za-z]{2}$"
                            }
                        },
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    },
                    "session": {
                        "title": "Session bootstrap",
                        "type": "object",
                        "description": "Optional live-mode session material such as cookies, headers, and user agent."
                    },
                    "rpcIds": {
                        "title": "RPC overrides",
                        "type": "object",
                        "description": "Optional rpcids overrides for search_creatives, get_creative_by_id, and get_advertiser_by_id."
                    },
                    "baseUrl": {
                        "title": "Base URL override",
                        "type": "string",
                        "description": "Optional override for the Transparency Center origin. Leave empty for production.",
                        "default": "https://adstransparency.google.com"
                    },
                    "requestTimeoutSecs": {
                        "title": "Request timeout seconds",
                        "minimum": 1,
                        "maximum": 120,
                        "type": "number",
                        "description": "HTTP timeout for live-mode requests.",
                        "default": 30
                    },
                    "debug": {
                        "title": "Debug",
                        "type": "boolean",
                        "description": "Enable extra debug logging for local and remote troubleshooting.",
                        "default": false
                    },
                    "keepDebugArtifacts": {
                        "title": "Keep debug artifacts",
                        "type": "boolean",
                        "description": "Keep intermediate artifacts instead of cleaning them after the run.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
