· 6 min read · by the Devil Scrapes team

Does This Company Run Google Ads? Screen Domains in Bulk

How to answer 'does this company run Google Ads' for thousands of domains at once, with a Python snippet and honest pricing math.

web-scrapingapify

Quick answer: To find out whether a company runs Google Ads right now, check the Google Ads Transparency Center for that domain — but there’s no bulk mode in the UI, so checking a thousand domains by hand isn’t realistic. Our Google Ads Transparency Scraper has a screeningMode flag that turns the same lookup into one row per domain — has_ads_detected, ad_count, first/last-seen dates, a sample creative link — billed once per domain instead of once per ad, at $0.20 per run plus $0.003 per domain screened.

“Does this company run Google Ads?” at scale

“Does this company run Google Ads?” sounds like a small question, but it’s the first filter in a lot of real workflows. A lead-gen team qualifying a prospect list of 2,000 marketing-agency prospects doesn’t need every creative Nike has ever run — they need one bit per domain: is this business spending on Google right now, yes or no. A compliance team sweeping a portfolio of 500 franchise sites needs to know which ones are running ads at all before deciding which ones are worth a deeper creative audit. Neither of those is a per-creative export job. Both of them are a domain-screening job, and the Transparency Center’s public UI has no bulk mode for it — you’d be pasting domains into a search box one at a time.

What screening mode actually returns

The Google Ads Transparency Scraper already talks to Google’s internal SearchCreatives RPC to pull individual ad creatives by brand domain or advertiser ID. Domain ad-screening mode doesn’t add a new endpoint or a new request — it aggregates the same pull differently. Set screeningMode: true in the input and each dataset row becomes one input target instead of one creative:

{
  "domain": "nike.com",
  "has_ads_detected": true,
  "ad_count": 40,
  "first_seen_ts": 1761145807,
  "last_seen_ts": 1778871417,
  "sample_creative_url": "https://adstransparency.google.com/advertiser/AR18378488041124659201/creative/CR15771942603307614209?region=anywhere"
}

has_ads_detected is the yes/no answer to the question in this post’s title. ad_count gives you a rough sense of scale without paying for every individual creative row. first_seen_ts / last_seen_ts tell you how long the campaign activity has been running. sample_creative_url is a deep link back into the Transparency Center in case you want to eyeball one ad before committing to a full creative pull for that domain.

A domain that isn’t advertising doesn’t fail the run — it finishes as a normal, successful row:

{
  "domain": "example.com",
  "has_ads_detected": false,
  "ad_count": 0,
  "first_seen_ts": null,
  "last_seen_ts": null,
  "sample_creative_url": null
}

That distinction matters for anyone scripting a screening sweep: a “no” is data, not an error. You can trust has_ads_detected: false to mean “we checked and found nothing in the window,” not “the request broke.”

Running a screening sweep in Python

from apify_client import ApifyClient

client = ApifyClient("<APIFY_API_TOKEN>")

run_input = {
    "searchDomains": [
        "nike.com",
        "adidas.com",
        "example.com",
    ],
    "screeningMode": True,
    "maxResults": 1000,
    "maxPages": 25,
}

run = client.actor("DevilScrapes/google-ads-transparency").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    status = "advertising" if item["has_ads_detected"] else "no ads found"
    print(f"{item['domain']}: {status} ({item['ad_count']} ads)")

Swap the three sample domains for a list of a few hundred or a few thousand prospect domains and the loop is unchanged — each domain is an independent target within the same run, and the RPC pull for one domain doesn’t depend on another.

The pricing math

Domain ad-screening mode bills on the same ad-result event as per-creative mode, but the event fires once per screened domain instead of once per creative. That’s the whole trick: screening 1,000 prospect domains costs the same as scraping 1,000 individual ad creatives, even though most of those domains will return dozens of creatives each in per-creative mode.

EventPriceWhen charged
actor-start$0.20Once per run
ad-result (screening row)$0.003Once per domain screened

Worked example: screening 1,000 domains costs $0.20 + (1,000 × $0.003) = $3.20 total, regardless of whether any given domain runs zero ads or a few hundred. Compare that to per-creative mode on the same 1,000 domains — if even a fraction of them are active advertisers running dozens of creatives each, the creative count (and therefore the bill) climbs fast. Screening first, then pulling full creative sets only for the domains that come back has_ads_detected: true, is the cheaper two-step path for anything larger than a handful of domains.

ad_count is capped by the same maxResults and maxPages budget as per-creative mode — a domain flagged has_ads_detected: true with ad_count: 40 may be running more than 40 ads; it’s a floor, not a hard total. Raise maxPages if you need a tighter count on a specific domain, though for a first-pass qualification sweep the boolean flag is usually all a lead-gen or compliance workflow needs.

The honest caveat: a “yes” doesn’t always mean what you think

Screening mode reports whatever the Transparency Center’s RPC attributes to a domain, and that attribution runs on landing domain, not brand ownership. A domain can legitimately show has_ads_detected: true because some advertiser is using it as a landing page target without being the business you associate with that domain — a redirect domain, a tracking domain, or a domain reused across campaigns for reasons that have nothing to do with the company you’re screening. If example.com (or any domain with a long, shared history on the web) comes back positive, don’t take that as proof the company behind it is running a live campaign — check sample_creative_url before you act on the flag. Screening mode tells you Google’s RPC associates ad activity with a domain; it doesn’t independently verify who controls that domain today.

We’d rather publish that caveat than let a screening sweep look more authoritative than it is. The same applies to region, which is display-only metadata on every row — Google’s SearchCreatives RPC ignores it as a filter, something we verified empirically rather than assumed.

Run it on Apify

Start with Google Ads Transparency Scraper — the first run on a new Apify account uses $5 of free credit, no card required, which is roughly 1,600 domains at screening-mode pricing. Flip screeningMode on, paste your domain list, and export the yes/no flags straight to CSV for your qualification pipeline.

FAQ

How do I check if a company runs Google Ads?

Search the domain in the Google Ads Transparency Center manually for one-off checks, or run the Google Ads Transparency Scraper with screeningMode: true for a batch of domains — it returns has_ads_detected: true/false per domain in one run.

Can I screen thousands of domains in a single run?

Yes. searchDomains accepts a list, and each domain is scraped as an independent target within the run. maxResults (default 1,000) caps the total dataset size across all targets combined, so raise it if you’re screening a very large list in one go.

Does screening mode cost the same as pulling every creative?

No — it’s usually cheaper for a large domain list. Screening bills once per domain ($0.003) regardless of how many ads that domain runs, while per-creative mode bills once per creative. A domain running 200 ads costs $0.003 to screen but $0.60 to fully export.

What does it mean if a domain shows ads but I don’t recognize the company?

It means Google’s Transparency Center associates that landing domain with at least one active ad, not that the company you know by that name is definitely the advertiser. Check sample_creative_url for the actual creative and advertiser before treating the flag as confirmed — some domains get used as landing pages for reasons unrelated to their public-facing owner.

Want this data without the engineering?

Every Actor in the fleet is pay per result and maintained daily. If the one you need doesn't exist, we'll build it.