Google Ads Transparency Scraper avatar

Google Ads Transparency Scraper

Pricing

from $1.00 / 1,000 ads

Go to Apify Store
Google Ads Transparency Scraper

Google Ads Transparency Scraper

Every ad a company runs on Google, from the Ads Transparency Center: headline, description, regions, dates and payer. Reads text ads shown only as images (OCR). Or check if ads point to a domain. $0.001 per ad, no start fee, no caps. AI-agent friendly: summary rows come first.

Pricing

from $1.00 / 1,000 ads

Rating

0.0

(0)

Developer

Otter Fetch

Otter Fetch

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 hours ago

Last modified

Categories

Share

See every ad a company runs on Google, or check whether any Google ads point to a website. The Actor reads the public Google Ads Transparency Center for you and gives you clean rows you can sort, filter and export. Not affiliated with Google.

You pay per ad returned (and a small add-on when it reads text out of an image). You never pay for empty results in ads mode.

Why this one

  • Clean ad copy. Headline and description as separate fields, read from the image when Google only shows a picture (87 to 89 of 100 Nike ads had a clean headline in our tests). Keyword-insertion templates are filled in. In our tests, 92% of Search text ads show their copy only as an image. The Actor reads that text (OCR) by default.
  • Region filters that work. Other scrapers often return 0 ads for the United States (see the FAQ).
  • No 35/100/1,000 ad caps. You set your own limit with maxAdsPerTarget. Use 0 for no limit.
  • Plain statuses. When a target has no ads, you get a free row that says why and what to try.
  • Two modes in one Actor. Get every ad for a company, or get a yes or no for each website.
  • Speed. 100 ads in about 2 minutes 15 seconds with text reading on, about 90 seconds without, under 15 seconds with listingOnly.

Quick start

  1. Pick Mode: Ads or Domain check.
  2. Type your Targets, one per line: a website (nike.com), an advertiser ID (AR16735076323512287233), a Transparency Center link, or a brand name. Or paste a CSV or Google Sheets link in Import targets from a link.
  3. Set a Region, Date range and Max ads per target if you want. The default is 100; the form is prefilled with 20 for a small first run.
  4. Click Start. When it ends, open the Overview view, or export the dataset as CSV.

Google blocks most cloud servers, so the Actor uses residential connections. They go through Apify residential proxies. Proxy costs are included in the price.

What you get

Real rows from cloud runs (2026-10-22 for the first four):

advertiserformatheadlinedays runningtext_source
Nike, Inc.textNike® Official Site140ocr
Nike Retail BVtextLe site officiel de Nike1824structured
Hubspot, Inc.textHubSpot CRM Platform31ocr
Canva, Pty LtdvideoStart designing with Canva today45structured
Cebu Air Inc.textCebu Pacific Air - Flights to Boracay1531ocr

A domain check row for nike.com: ads_point_here true, 80,000 to 90,000 ads, active in the last 30 days, top advertiser Nike Retail BV.

See Advanced for full rows.

Pricing

Pay per event. You pay for results, not for time.

EventPriceCharged when
ad$0.001One ad row was returned. Summary, status, blocked and failed rows are free. With listingOnly on this is the only event.
ad-text-ocr$0.001Ads mode only, on top of ad: the text of that ad was read from its image. Never charged when listingOnly is on. Not charged when readImageText is off, no text was found, or the text was unreadable (for example Thai or Korean ad images).
domain-check$0.001One domain was checked: every verdict, yes or no, is billed. Domains that could not be checked (invalid, blocked or skipped) are not.

Prices shown are the current list prices; Apify shows the live price on the Actor page.

What a run costs: 100 ads with text reading on cost about $0.13 ($0.10 for the ads, plus $0.001 for each ad whose text was read; at most $0.20). 1,000 domain checks cost $1.

What 1 ad actually costs

An ad costs $0.001. If its text was read from an image, add $0.001, so $0.002 at most. That add-on is +$0.001 per ad where text was read. Nothing is charged when no text was read. Turn readImageText off and ads cost $0.001 each.

With listingOnly on, every ad costs $0.001 and ad-text-ocr is never charged, even if readImageText is on. The maximum cost per run also counts each ad as $0.001 in that case.

So 1,000 ads cost between $1 and $2, depending on how many were text ads read with OCR.

You never pay for empty results in ads mode. In ads mode these are free: status rows, summaries, blocked lookups and the start-up check that makes sure Google is answering normally. In domain check, a "no ads point here" answer is a real answer, so it is billed like a "yes".

Other facts:

  • No start fee, no per-GB fee and no fee for time spent.
  • maxAdsPerTarget is a hard limit: the run never fetches or bills more ads than that for a target.
  • The Actor respects your maximum cost per run. It works out how many results the budget covers before it starts and lists the rest as skipped (skipped_budget).

What it does

  • Ads mode. For each target, returns one ad row per ad and one target_summary row (the verdict, how many ads, which advertisers). Ad rows include the format (text, image or video), headline, description, landing page, first and last shown dates, days running, the countries it ran in with impression ranges, and the payer name.
  • Domain check mode. For each website, returns one domain row that answers: do any Google ads point to this site? It also says whether any ran in the last 30 days.
  • Filters. Region (country), date range, ad format and a limit per target.
  • Free explanation rows. A target with no ads, a skipped target or a blocked target gets a status row in plain English. It is never billed.

Who it is for

Marketers

See what a competitor is running, how long each ad has been live, and which landing pages they send people to. Long-running ads are usually the ones that work.

Agencies

Run a list of client or prospect domains in one go and export a spreadsheet. Use Domain check to find out which prospects advertise at all before you pitch them.

Lead generation

Check a long list of domains for "is this company spending on Google ads?" and keep only the ones that are. Use the advertiser_match column to see if an advertiser name looks like the site (it compares names only and is a hint, not proof, see the FAQ).

AI agents

One clear input, one row type per question, and a plain status and reason on every non-result. You are billed only for results. Read only rows where type is target_summary or domain for a compact answer.

The Advanced section has a note on choosing fields when you fetch dataset items.

Example inputs

Field keys below are the real input keys. Only targets (or importUrl) is required.

Marketers: a competitor's recent US ads

{
"mode": "ads",
"targets": ["nike.com"],
"region": "US",
"dateRange": "last_90_days",
"maxAdsPerTarget": 200
}

Agencies: all ads for two advertisers, text ads only

{
"mode": "ads",
"targets": ["AR16735076323512287233", "hubspot.com"],
"format": "text",
"maxAdsPerTarget": 100,
"maxTargets": 50
}

Lead generation: which of these sites run Google ads?

{
"mode": "domainCheck",
"importUrl": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit",
"domainActiveWindow": true
}

Just the ad list: no text, regions or payer

{
"mode": "ads",
"targets": ["nike.com"],
"maxAdsPerTarget": 500,
"listingOnly": true
}

AI agents: a small, low-cost look

{
"mode": "ads",
"targets": ["hubspot.com"],
"maxAdsPerTarget": 20,
"readImageText": false,
"adDetails": false
}

FAQ

Why do other scrapers return 0 ads for the US? Two reasons. First, Google uses its own region codes, not the usual country codes. The Actor maps codes like US for you. Second, Google returns nothing when you look up a subdomain. The Actor checks the main domain instead: shop.globe.com.ph becomes globe.com.ph, and www.nike.com becomes nike.com.

Why does the Actor read text from images? In our tests, 92% of Search text ads show their copy only as an image. Without OCR you would get empty headlines. The Actor reads that text (OCR) by default, for +$0.001 per ad where text was read. To turn it off, clear Read ad text from images (+$0.001 per ad where text was read) in the form (readImageText set to false). The headline and description will then be empty for those ads, and you save the add-on.

Is there a cap on how many ads I can get? No 35/100/1,000 ad caps. You choose with Max ads per target (maxAdsPerTarget). The default is 100; the form is prefilled with 20 for a small first run. Use 0 for no limit. Be careful with large brands: nike.com has more than 80,000 ads, so 0 there is a very large run. Set a limit first.

How long does a run take? In our tests (nike.com, 100 ads, default settings), 100 ads took about 2 minutes 15 seconds with text reading on. With Read ad text from images off, they took about 90 seconds. With listingOnly on, they took under 15 seconds. Reading text from images is the slow part: it is what fills the headline and description of most text ads.

What happens if my region has no ads? Retry anywhere when the region has no ads (retryAnywhere) is off by default, so a one-country request is never billed for other countries. You get a free status row (region_too_narrow) that says how many ads exist with no region filter. Turn it on to fetch ads from all countries instead. Those rows are marked with region_fallback.

Can I pick Search, YouTube or Maps ads? There is no platform filter (Search, YouTube, Maps) yet: results cover every platform.

How exact is a brand name? Brand names are matched through Google's suggestions and can pick the wrong company. Domains and advertiser IDs are exact. Some brands (for example McDonald's) have no domain suggestions, so enter their domain instead.

What does advertiser_match mean? In Domain check it compares advertiser names (the top advertisers in the sample) with the domain or brand you gave. It is based on names only and does not verify domain ownership: it is a hint, not proof. advertiser_match_reason is name when a name looked like it and none when none did. An agency can advertise a client's site under its own name, and that shows as none.

What does "ads point here" mean in domain check? It means Google ads exist whose landing page is on that domain. It does not say the site owner is the advertiser. Ended advertisers may not show up when you search by domain.

Can I paste a Transparency Center link? Yes. Only the region part of a pasted link is used. Date parameters in links are ignored: use the form's date range (Date range, Custom start date and Custom end date).

What do the totals mean? Google shows ad totals as buckets, so total_ads_range has a low and a high number. ads_returned is how many ads were found for the target. Ads found (up to your limit). Ad rows can be fewer when the run stops early or an ad was already returned for another target.

Why is a target skipped? Three status reasons cover skips, and none is billed. skipped_limit: you hit Max targets (maxTargets). skipped_budget: the run reached your maximum cost per run, so the rest was left out. skipped_timeout: the run reached its time limit before that target. Raise the limit or split the list across runs. A blocked row means Google refused the requests after several retries: try again in a few minutes. A failed row means something went wrong on our side while handling that target. It is not billed. Try again, and report it in the Issues tab if it repeats. If every target fails this way, the run ends as failed instead of showing an empty result.

Is this a Google Ads Transparency API? Google has no official API for this. The Actor reads the public Transparency Center and you can call it through the Apify API, so it works like one: send targets, get rows back.

Is this a Google Ads Transparency Center scraper? What about the Google Ads Library? Yes. It is a Google Ads Transparency Center scraper. Some people call that public lookup the Google Ads Library; it is the same place.

Can I use it as a Google ad spy tool for competitor Google ads? Yes. Enter a competitor's website or advertiser ID in Ads mode to list their ads, how long each has run and where it points. Long-running ads are usually the ones that work.

How do I check if a website runs Google Ads? Use Domain check mode. You get one row per website that says whether any Google ads point to it and whether any ran in the last 30 days.

Is this affiliated with Google? Not affiliated with Google. Data comes from the public Google Ads Transparency Center.

Advanced

Sample output

These rows were produced by the Actor's own row builders from recorded data, so the fields are real. Numbers will differ on your run. Long lists are shortened to keep this page readable. The ad row is a real Cebu Pacific text ad whose headline and description were read from its image. The domain row is for nike.com.

target_summary (one per target; with a limit it comes before its ads, with no limit it comes after them):

{
"type": "target_summary",
"input": "AR03755644507429797889",
"status": "success",
"verdict": "has_ads",
"query_kind": "advertiser",
"resolved_via": "advertiser_id",
"advertisers": [{"name": "LL Law Firm", "id": "AR03755644507429797889", "ads": 3}],
"total_ads_range": {"lo": 9, "hi": 9},
"ads_returned": 3,
"ads_active_last_30_days": 3,
"format_mix": {"text": 3},
"first_seen": "2025-06-09",
"last_seen": "2026-10-20",
"transparency_url": "https://adstransparency.google.com/advertiser/AR03755644507429797889",
"region": null,
"region_fallback": false
}

ad (one per ad, abbreviated):

{
"type": "ad",
"query": "cebupacificair.com",
"status": "success",
"advertiser_id": "AR07044148030781521921",
"advertiser_name": "Cebu Air Inc.",
"ad_id": "CR11309760530983419905",
"ad_url": "https://adstransparency.google.com/advertiser/AR07044148030781521921/creative/CR11309760530983419905",
"format": "text",
"headline": "Cebu Pacific Air - Flights to Boracay",
"description": "Book and save on your next flight to Boracay. Check out our low fares today!",
"first_shown": "2022-08-13",
"last_shown": "2026-10-21",
"days_running": 1531,
"text_source": "ocr",
"region_fallback": false
}

Some Search ads use Google keyword insertion, where the ad data holds a template such as {KeyWord:Nike Shoes}. headline and description show the default text ("Nike Shoes"), and headline_template and description_template keep the text exactly as Google has it. They are empty when the ad has no template. A template with no default text ({KeyWord}) cannot be filled in and is left as written.

text_source says where the words came from: ocr means they were read from the ad image. With Fetch ad details on (the default), the full row also has the countries it ran in, with dates and impression ranges, and the payer name. If the image is in a script the reader cannot read (for example Thai or Korean), the text is left empty, text_source is none, the extraction entries for headline and description say unreadable, and there is no OCR charge. See the Ads view for every column.

domain (one per domain in Domain check):

{
"type": "domain",
"input": "nike.com",
"query": "nike.com",
"status": "success",
"ads_point_here": true,
"total_ads_range": {"lo": 80000, "hi": 90000},
"sample_size": 40,
"top_advertisers": [
{"name": "Nike Retail BV", "id": "AR18378488041124659201", "ads": 24},
{"name": "Nike, Inc.", "id": "AR16735076323512287233", "ads": 10}
],
"advertiser_match": true,
"advertiser_match_reason": "name",
"latest_last_shown": "2026-10-21",
"active_last_30_days": true,
"active_last_30_days_range": {"lo": 10000, "hi": 20000}
}

Totals are ranges (for example 80,000 to 90,000) because Google only shows buckets, not exact counts.

Notes for AI agents

When you fetch dataset items with the fields parameter (for example through an MCP server), ask for top_advertisers, the whole list. Do not ask for top_advertisers.name: it is not a column, so you would get nothing back.

Dataset views and row types

The dataset has four views in the Apify Console: Overview, Ads, Domain check and Status. Each view shows the columns for one kind of row. Views cannot filter rows, so a view still lists every row and leaves the columns that do not apply empty. To get one kind of row only, export the dataset and filter the type column. The values are ad, target_summary, domain and status. In Google Sheets, use Data, Create a filter on the type column. With a limit (the default is 100), each target's summary row comes before its ads. With no limit (0), ads are delivered page by page and the summary row comes after them.

Status reasons

Each free status row has a reason column: invalid_target, brand_not_found, no_ads, region_too_narrow, date_too_narrow, blocked, failed, skipped_limit, skipped_budget or skipped_timeout. The message column says in plain English what to try.

All inputs

Field (key)What it does
Mode (mode)ads (every ad per target) or domainCheck (do ads point to each domain?). Default ads.
Targets (targets)One per line: a website domain, an advertiser ID, a Transparency Center link or a brand name.
Import targets from a link (importUrl)A CSV link or a Google Sheets link shared as "anyone with the link". One target per row in the first column.
Region (region)A country, or anywhere for all countries. Default anywhere.
Retry anywhere when the region has no ads (retryAnywhere)When the region has no ads, fetch from all countries and mark the rows. Default off.
Date range (dateRange)all, last_30_days, last_90_days, last_12_months or custom.
Custom start date (startDate)First day (YYYY-MM-DD). Used only with a custom date range.
Custom end date (endDate)Last day (YYYY-MM-DD). Used only with a custom date range.
Ad format (format)all, text, image or video.
Max ads per target (maxAdsPerTarget)Hard limit per target. The default is 100; the form is prefilled with 20 for a small first run. 0 means no limit.
Listing only (fastest: no ad text, regions or payer) (listingOnly)Returns only the listing fields of each ad (advertiser, format, dates, ad link). No preview, details or OCR requests, so the text, countries, payer and headline_template fields are empty and their extraction entries say missing. Each ad costs $0.001 and ad-text-ocr is never charged. Default off.
Read ad text from images (+$0.001 per ad where text was read) (readImageText)OCR for image-only text ads. Default on.
Fetch ad details (adDetails)Adds countries with dates, impression ranges and the payer name. One extra request per ad, no extra charge. Default on.
Also check the last 30 days (domain check only) (domainActiveWindow)Domain check only. Adds whether ads ran in the last 30 days. Same price.
Max targets (maxTargets)Optional safety limit for scheduled runs. Extra targets are listed as skipped and not charged.

Issues

Report problems in the Issues tab. Include the run link and the target that went wrong.