# Google Ads Presence Lookup: ads transparency checker from $3/1k (`accountable_eel/google-ads-presence-lookup`) Actor

Google Ads transparency checker by domain — see if a brand or domain is running Google Ads, straight from Google's own Ads Transparency Center. One row per company: advertiser identity, verified status, ad counts by format and recency, sample ad links. Never charged for a miss.

- **URL**: https://apify.com/accountable\_eel/google-ads-presence-lookup.md
- **Developed by:** [Adrian Voss](https://apify.com/accountable_eel) (community)
- **Categories:** Lead generation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.28 / 1,000 advertiser founds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

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

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

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

# README

## Google Ads Presence Lookup: Google Ads Transparency Checker

**Paste a list of company domains (or brand names). Get back one row per company telling you whether it's running Google Ads right now — with the advertiser's verified identity, how many ads are in Google's library, how many ran in the last 30 days, the format mix (image / text / video), first and last seen dates, and links to sample ads.** Data comes straight from Google's own [Ads Transparency Center](https://adstransparency.google.com/), the public register of every ad shown by verified Google advertisers.

### Who it's for

- **Outbound and RevOps teams** enriching a lead list: "does this prospect spend on Google Ads?" is a buying-intent and budget signal you can filter on in Clay, n8n, or a spreadsheet.
- **Agencies prospecting for ad clients**: find companies that are *already* advertising (they have budget) or *not yet* advertising (they need you).
- **Competitor and market analysts** who want a quick per-company read — active ad program or not, how heavy, which formats — without scraping thousands of creatives.
- **AI agents** that need a single structured answer per company, callable over plain HTTP.

### Why this one

Every other Google Ads actor on Apify is a **bulk creative scraper**: you give it a query, it downloads hundreds or thousands of individual ads, and you pay per ad. That's the right tool for building a creative-intelligence archive — and the wrong tool for enriching a 5,000-row lead list, where you'd pay for 500 ads from one company just to learn "yes, they advertise."

This actor asks the opposite question: **one input company → one output row**, sized and priced as an enrichment column.

- **One row per company**, not one per ad. Predictable output, predictable cost.
- **Never charged for a miss.** A company with no ads in the Transparency Center costs you nothing.
- **Domains beat brand names.** A domain (`acme.com`) is matched against ads that actually link to it — the strongest possible signal. Brand names are matched against Google's advertiser register with exact-name ranking (a search for "nike" on Google's own site ranks a small Kenyan advertiser named "Nike" above Nike, Inc. — this actor corrects for that).
- **Verified identity included.** Google's advertiser verification status, legal name, and country come from the advertiser's own Transparency page.

### What you get

One dataset row per input, with these columns (all included by default; select fewer with the `columns` input):

| Column | Meaning |
| --- | --- |
| `advertiserName` / `advertiserId` | The top advertiser behind this domain's ads (or the matched advertiser for a brand-name query) and its stable `AR…` Transparency Center ID |
| `verified` | Whether the advertiser passed Google's identity verification |
| `legalName` | The advertiser's legal name on file with Google |
| `advertiserCountry` | Advertiser's registered country (ISO code) |
| `creativeCount` / `creativeCountLowerBound` | Estimated ads in Google's library — Google reports a range; `creativeCount` is the upper estimate its own UI displays ("~9K ads"), exact for small advertisers |
| `creativesLast30d` / `activeLast30d` | Estimated ads shown in the last 30 days, and the yes/no flag most lists filter on |
| `imageAds` / `textAds` / `videoAds` | Estimated ad counts by format — "are they running video?" in one column |
| `firstSeenAt` / `lastSeenAt` | Earliest and latest ad-shown dates among the sampled creatives |
| `advertiserCount` / `advertisersSeen` | Distinct advertisers observed running ads to this domain (agencies, resellers, and regional entities show up here) |
| `sampleCreativeUrls` | Up to 5 direct links to real ads in the Transparency Center |
| `transparencyUrl` | The advertiser's public Transparency Center page |
| `inputType` / `region` | Whether the input matched as a `domain` or `brand`, and the region scope (`anywhere`) |

### How to use Google Ads Presence Lookup — Is This Domain Running Ads?

1. **In the Apify Console.** Open the actor page and click **Start** — the `queries` field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
2. **Via the API.** Call it directly with a POST request — no Console needed once you have an API token:
   ```bash
   curl "https://api.apify.com/v2/acts/accountable_eel~google-ads-presence-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"queries":["nike.com","booking.com"]}'
   ```
3. **On a schedule.** Save this actor as an Apify **Task** with the input you want, then add a **Schedule** (hourly, daily, weekly) so it runs on its own — no server of your own required.

### Input

```json
{
  "queries": [
    "nike.com",
    "booking.com"
  ]
}
```

One brand name or company domain per line. Domains match more reliably than brand names. Accepted formats: nike.com, https://www.nike.com/gb/, Nike, Inc..

### Sample output

| query | found | status | advertiserName | advertiserId | verified | legalName | advertiserCountry | creativeCount | creativeCountLowerBound | creativesLast30d | activeLast30d | imageAds | textAds | videoAds | firstSeenAt | lastSeenAt | advertiserCount | advertisersSeen | sampleCreativeUrls | transparencyUrl | inputType | region | scrapedAt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| booking.com | true | OK | Booking.com | AR02934798844673654785 | false | Booking.com | NL | 15400000 | 15300000 | 12500000 | true | 15400000 | 4000 | 5000 | 2021-10-25 | 2026-08-31 | 1 | \[{"advertiserId":"AR02934798844673654785","advertiserName":"Booking.com"}] | \["https://adstransparency.google.com/advertiser/AR02934798844673654785/creative/CR01274045157221597185?region=anywhere","https://adstransparency.google.com/advertiser/AR02934798844673654785/creative/CR06634413802920083457?region=anywhere","https://adstransparency.google.com/advertiser/AR02934798844673654785/creative/CR11308336422907281409?region=anywhere","https://adstransparency.google.com/advertiser/AR02934798844673654785/creative/CR04582091563454169089?region=anywhere","https://adstransparency.google.com/advertiser/AR02934798844673654785/creative/CR13333864921213960193?region=anywhere"] | https://adstransparency.google.com/advertiser/AR02934798844673654785?region=anywhere | domain | anywhere | 2026-08-31T06:30:25.604Z |

### Pricing

$3 per 1,000 brands or domains, plus a $0.00005 start fee. Misses (`found:false`) are never charged.

Compare: assembling the same answer from a bulk creative scraper at ~$0.80 per 1,000 *ads* means paying for every ad a big advertiser runs just to learn that they advertise — a single Nike-sized company can cost more than this actor's entire 1,000-company run. Clay's own enrichment credits run $0.08–0.40 per row.

### Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

```bash
curl "https://api.apify.com/v2/acts/accountable_eel~google-ads-presence-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"queries":["nike.com","booking.com"]}'
```

**n8n.** Add an HTTP Request node: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~google-ads-presence-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body Content Type `JSON`, JSON Body `{"queries":["nike.com","booking.com"]}` (swap in an expression from an earlier node for a real value).

**Clay.** Add an "HTTP API" column: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~google-ads-presence-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body `{"queries":["{{brand or domain}}"]}`, mapping the row's brand or domain into the `queries` array.

**MCP.** In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Google Ads Transparency Checker | Apify" — the agent will find and run this actor.

### Tips

- **Prefer domains over brand names.** `acme.com` matches ads by their landing-page domain — unambiguous. "Acme" has to go through advertiser-name search, which can hit same-named companies in other countries. The `inputType` column tells you which path each row took.
- **`activeLast30d` is the enrichment flag.** `creativeCount` includes historical ads; a company can have thousands in the library and none running this month.
- **Counts are Google's own estimates.** For large advertisers Google reports order-of-magnitude ranges (8,000–9,000 for Nike, Inc. — the UI shows "~9K"); for small advertisers they're exact. `creativeCount` is the upper bound, `creativeCountLowerBound` the lower.
- **`firstSeenAt` is sampled, not global.** It's the earliest first-shown date among the sampled creatives (newest-first ordering), so treat it as "advertising since at least…", not the advertiser's true first-ever ad date.
- **Multiple advertisers per domain is normal.** Large brands advertise through regional entities and agencies (`nike.com` shows Nike Retail BV, Nike, Inc., WPP Media, and more). `advertisersSeen` lists what was observed; the row's identity fields describe the most frequent one.
- **Keep the RESIDENTIAL proxy default.** Google serves these endpoints happily to residential IPs; shared datacenter IPs are much more likely to be rate-limited mid-run.

### FAQ

**What does "no ads found" (`found: false`) actually mean?**
No advertiser in Google's Transparency Center currently has (or recently had) ads linking to that domain, or no advertiser register entry matched your brand name. It does not distinguish "never advertised" from "ads aged out of the library". Misses are never charged.

**How fresh is the data?**
It's read live from Google's Transparency Center at run time — the same data Google shows the public, including ads shown the same day (`lastSeenAt` is often today's date for active advertisers).

**Which regions are covered?**
The lookup runs with Google's "Anywhere" region scope — ads shown in any country count. Per-country breakdowns aren't included; `advertiserCountry` is the advertiser's registered home country, not where its ads run.

**Are the ad counts exact?**
Exact for small advertisers; Google-reported estimate ranges for large ones (the same "~9K ads" its own UI shows). Date filtering (the 30-day count) uses Google's Pacific-time day boundaries.

**Does this download the actual ad creatives?**
No — that's deliberate. You get up to 5 sample ad links plus counts by format. If you need every creative's text and media, use a bulk creative scraper; this actor is the cheap per-company presence check that tells you which companies are worth that deeper pull.

**Can I look up an advertiser by their AR… ID?**
Not directly in this version — input a domain or brand name. The row gives you the `advertiserId` and `transparencyUrl` for any deeper manual digging.

**Rate limits / getting blocked?**
The actor uses Apify RESIDENTIAL proxies by default and retries transient failures. If a run reports `BLOCKED` rows, lower `maxConcurrency` (5 by default) — Google rate-limits bursts, not sustained modest traffic.

**Is this legal?**
The Ads Transparency Center is Google's own public transparency register, built so anyone can inspect who advertises what. This actor reads only that public data — no login, no personal data.

### Related actors

- [Tech Stack Lookup](https://apify.com/accountable_eel/tech-stack-lookup) — what a website is built on (CMS, analytics, payments), another per-domain enrichment column.
- [Company Domain Enrichment](https://apify.com/accountable_eel/company-domain-enrichment) — RDAP, DNS, email route, tech and hiring signals for a domain in one call.
- [Email Deliverability Check](https://apify.com/accountable_eel/email-deliverability-check) — MX/provider verification for outbound lists.

# Actor input Schema

## `queries` (type: `array`):

One brand name or company domain per line. Domains match more reliably than brand names. Accepted formats: nike.com, https://www.nike.com/gb/, Nike, Inc.. You're only charged for the ones we actually find — a miss costs nothing.

## `testRun` (type: `boolean`):

Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.

## `onlyFound` (type: `boolean`):

Only keep rows where something was actually found. Misses are always free, whether or not you show them here.

## `includeKeywords` (type: `array`):

Optional. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.

## `excludeKeywords` (type: `array`):

Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.

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

Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit.

## `columns` (type: `array`):

Choose which pieces of information to include in each result row. All are included by default.

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

Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.

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

Apify Proxy config. Residential recommended for anti-bot-sensitive targets.

## Actor input object example

```json
{
  "queries": [
    "nike.com",
    "booking.com"
  ],
  "testRun": false,
  "onlyFound": false,
  "includeKeywords": [],
  "excludeKeywords": [],
  "columns": [
    "advertiserName",
    "advertiserId",
    "verified",
    "legalName",
    "advertiserCountry",
    "creativeCount",
    "creativeCountLowerBound",
    "creativesLast30d",
    "activeLast30d",
    "imageAds",
    "textAds",
    "videoAds",
    "firstSeenAt",
    "lastSeenAt",
    "advertiserCount",
    "advertisersSeen",
    "sampleCreativeUrls",
    "transparencyUrl",
    "inputType",
    "region"
  ],
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (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 = {
    "queries": [
        "nike.com",
        "booking.com"
    ],
    "includeKeywords": [],
    "excludeKeywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("accountable_eel/google-ads-presence-lookup").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 = {
    "queries": [
        "nike.com",
        "booking.com",
    ],
    "includeKeywords": [],
    "excludeKeywords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("accountable_eel/google-ads-presence-lookup").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 '{
  "queries": [
    "nike.com",
    "booking.com"
  ],
  "includeKeywords": [],
  "excludeKeywords": []
}' |
apify call accountable_eel/google-ads-presence-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,accountable_eel/google-ads-presence-lookup"
        }
    }
}

```

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/kfSdwcVMqn2ouYOAs/builds/RhnXHGxcWCD7410aO/openapi.json
