Arcadium Data Scrapers
Home / Guides / Google Ads Transparency Scraper

How to use Google Ads Transparency Scraper

Step by step: in the Apify Store, over the API, from JavaScript or Python, in n8n, and from AI agents through MCP or LangChain.

$1.80 per 1,000 ads on the Free plan, down to $1.35 on higher plans (live Apify price on 2026-11-03).

1. In the Apify Store (no code)

  1. Open arcadium/google-ads-transparency and sign in to Apify (a free account works).
  2. Fill in the input form. The fields below are the ones the example uses.
  3. Set a maximum cost per run in the run options if you want a hard cap.
  4. Start the run. Rows appear in the Output tab as they arrive.
  5. Export the dataset as JSON, CSV or Excel, or connect an integration.
Input fieldTypeDescription
searchTermsarrayWhat to look up, one per line: a brand or company name such as "Nike" (matched to Google's verified advertisers, see 'Advertisers per name'), a landing domain such as "nike.com" (all advertisers whose ads point there), or an advertiser/creative link from adstransparency.google.com.
modestringads = one row per ad creative (default). advertisers = one row per matching advertiser with country and approximate ad count. monitor = only what changed since your last run: new and stopped ads per advertiser, plus one summary row per advertiser.
maxAdsPerAdvertiserintegerAds to return per advertiser (or per domain), newest 'last shown' first, for example 100. Default 40, up to 10,000.

Example input:

{
  "searchTerms": [
    "nike.com"
  ],
  "mode": "ads",
  "maxAdsPerAdvertiser": 20
}

2. Over the Apify API

The synchronous endpoint runs the actor and returns its rows in one call (for runs up to about five minutes; use the asynchronous run endpoint for longer ones).

curl -X POST "https://api.apify.com/v2/acts/arcadium~google-ads-transparency/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchTerms":["nike.com"],"mode":"ads","maxAdsPerAdvertiser":20}'

3. From JavaScript

// npm install apify-client
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/google-ads-transparency').call({
  "searchTerms": [
    "nike.com"
  ],
  "mode": "ads",
  "maxAdsPerAdvertiser": 20
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

4. From Python

# pip install apify-client
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/google-ads-transparency").call(run_input={
    "searchTerms": ["nike.com"],
    "mode": "ads",
    "maxAdsPerAdvertiser": 20,
})
items = client.dataset(run.default_dataset_id).list_items().items  # apify-client 3.x returns a Run object
print(items)

5. In n8n

Paste this node into a workflow (it is a plain HTTP Request node). Create a Header Auth credential with name Authorization and value Bearer <APIFY_TOKEN>; each returned row becomes one item for the next node.

{
  "nodes": [
    {
      "name": "Run arcadium/google-ads-transparency",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        0,
        0
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.apify.com/v2/acts/arcadium~google-ads-transparency/run-sync-get-dataset-items",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "{\"searchTerms\":[\"nike.com\"],\"mode\":\"ads\",\"maxAdsPerAdvertiser\":20}",
        "options": {
          "timeout": 300000
        }
      }
    }
  ],
  "connections": {}
}

6. From an AI assistant (MCP)

Add Apify’s MCP server to Claude Desktop, Cursor, VS Code or any MCP client, limited to this actor:

{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=arcadium/google-ads-transparency",
      "headers": {
        "Authorization": "Bearer <APIFY_TOKEN>"
      }
    }
  }
}

More on the MCP page.

7. From LangChain

# pip install langchain-apify   (reads APIFY_API_TOKEN from the environment)
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("arcadium/google-ads-transparency")
rows = tool.invoke({"run_input": {
    "searchTerms": ["nike.com"],
    "mode": "ads",
    "maxAdsPerAdvertiser": 20,
}})
# or give `tool` to an agent: create_react_agent(llm, [tool])

Sample output

One row, from the example in the actor’s README. Long text is shortened and lists are cut to two items.

{
  "rowType": "ad",
  "platform": "google-ads-transparency",
  "advertiserId": "AR04217635482122584065",
  "advertiserName": "Spotify USA Inc",
  "advertiserNameWithheld": false,
  "advertiserCountry": "US",
  "creativeId": "CR08508353801336389633",
  "adUrl": "https://adstransparency.google.com/advertiser/AR04217635482122584065/creative/CR08508353801336389633?region=GB",
  "format": "video",
  "firstShown": "2025-03-18",
  "lastShown": "2026-10-22",
  "daysShown": 520,
  "regionsShown": [
    "GB",
    "FR"
  ],
  "detailed": true,
  "impressionsMin": 500000,
  "impressionsMax": 600000,
  "regionStats": [
    {
      "region": "FR",
      "firstShown": "2025-03-25",
      "lastShown": "2026-10-21",
      "impressionsMin": 40000,
      "impressionsMax": 45000,
      "platforms": [
        {
          "platform": "youtube",
          "impressionsMin": 35000,
          "impressionsMax": 40000
        }
      ]
    }
  ],
  "contentKind": "video",
  "youtubeVideoId": "2BfJuvCtfEI",
  "youtubeUrl": "https://www.youtube.com/watch?v=2BfJuvCtfEI",
  "searchTerm": "AR04217635482122584065",
  "matchedBy": "advertiser"
}
FieldWhat it holds
rowTypeKind of row. Filter on this first. 'ad': one ad creative (charged as 'ad', or 'ad-detail' when detailed is true). 'ad-change': monitor mode, an ad that is new, resumed or stopped since the last run (charged like an ad row). 'advertiser': one matching advertiser (charged as 'advertiser'). 'summary': monitor mode, one row per advertiser and run (charged as 'advertiser-check'). 'error': an input could not be read; see code and message (free).
platformAlways 'google-ads-transparency'.
advertiserIdGoogle's advertiser id (AR...). Use it in 'advertiserIds' to fetch the same advertiser again.
advertiserNameVerified legal name of the advertiser as Google shows it. null when the name may belong to a private person (see advertiserNameWithheld).
advertiserNameWithheldtrue when Google shows a name that may be a private person (sole trader); we do not output it.
advertiserCountryCountry the advertiser is based in (verified by Google), two-letter code.
creativeIdGoogle's id of the ad creative (CR...).
adUrlPage of the ad on adstransparency.google.com (with the region when one region was filtered).
format'text', 'image' or 'video'. Text ads are often archived as an image of the ad (see imageUrl).
firstShownDay the ad was first shown, YYYY-MM-DD.
lastShownDay the ad was last shown, YYYY-MM-DD.
daysShownNumber of days Google showed the ad.
domainLanding domain, on domain searches.
previewUrlGoogle's preview script that renders the ad (what the website loads).
imageUrlArchived image of the ad (text and image ads), tpc.googlesyndication.com.
imageWidthWidth of imageUrl in pixels.
imageHeightHeight of imageUrl in pixels.
politicaltrue for election ads (they carry spend and impressions).
impressionsMinLower bound of total impressions where Google publishes them (political ads; EU/EEA with details). 0 means 'under impressionsMax'.
impressionsMaxUpper bound of total impressions; null with a set impressionsMin means 'impressionsMin or more'.
spendMinPolitical ads: lower bound of spend, in spendCurrency.
spendMaxPolitical ads: upper bound of spend, in spendCurrency.
spendCurrencyCurrency of spendMin/spendMax, e.g. USD.
regionsShownCountries where the ad was shown (two-letter codes); with details, every region in regionStats.
detailedtrue when the ad detail was read (includeDetails).
regionStatsWith details: one entry per region shown: region, firstShown, lastShown, impressionsMin/Max and per-surface impressions (search, youtube, shopping, maps, play) where Google publishes them (EU/EEA, political).
variationCountWith details: number of renderings (sizes, versions) of the creative.
contentKindWith details: what the decoded preview is: 'text', 'product' (Shopping), 'image', 'video', 'html' (rendered but no fields), 'unknown'.
headlineDecoded headline of a text ad, or product title of a Shopping ad.
descriptionDecoded description line of a text ad.
displayUrlDecoded display URL of a text ad, e.g. www.example.com/shoes.
businessNameBusiness name line of a text ad, or store name of a Shopping ad.
sitelinksSitelink texts of a text ad.
adTextAll visible text of the rendered ad, emails and phone numbers removed.
imageUrlsImage URLs found in the decoded ad (product images, YouTube thumbnail, archived images).
youtubeVideoIdYouTube video id of a video ad.
youtubeUrlYouTube watch link of a video ad.
searchTermThe input this row came from.
matchedByHow the input was resolved: 'advertiser' (id or link), 'name' (brand name lookup) or 'domain'.
scrapedAtWhen the row was read (ISO datetime).
changeTypeMonitor change rows: 'new' (first shown since the last check), 'resumed' (older ad active again) or 'stopped' (not shown in the last activeWithinDays days).
checkedAtMonitor rows: time of this check.
adsMinAdvertiser rows: lower bound of the number of ads Google lists for the advertiser.
adsMaxAdvertiser rows: upper bound of the number of ads.
advertiserUrlAdvertiser page on adstransparency.google.com.
verticalsAdvertiser rows for id inputs: Google's categories, e.g. commercial, political.
matchingDomainsAdvertiser rows for a name: landing domains Google suggests for the same text (not tied to this advertiser).
statusSummary rows: 'baseline' (first run, active ads recorded), 'changed' or 'unchanged'.
targetSummary rows: key of the saved state (advertiser or domain plus filters).
regionsSummary rows: the region filter of the check.
activeWithinDaysSummary rows: an ad is active when shown on one of the last N days.
activeAdsSummary rows: active ads now.
completeSummary rows: false when the active list hit maxActiveAdsPerAdvertiser (stopped ads are then not reported).
previousActiveAdsSummary rows: active ads at the previous check (null on a baseline).
newAdsSummary rows: ads first shown since the previous check.
resumedAdsSummary rows: older ads active again.
stoppedAdsSummary rows: ads no longer shown.
changesDeferredSummary rows: changes over maxChangesPerAdvertiser, reported on the next run.
previousCheckAtSummary rows: time of the previous check.
inputError rows: the input that failed.
codeError rows: invalid_input, not_found, no_match, blocked or unavailable.
messageError rows: what went wrong, in plain words.

Tutorials

Schedule it

In Apify Console, create a Task from your input and add a Schedule (for example daily). Each run writes a new dataset; integrations can push the rows to Google Sheets, Slack, a webhook or your database.