Google Ads Transparency Scraper — full ad copy + image OCR avatar

Google Ads Transparency Scraper — full ad copy + image OCR

Under maintenance

Pricing

from $0.80 / 1,000 ad results

Go to Apify Store
Google Ads Transparency Scraper — full ad copy + image OCR

Google Ads Transparency Scraper — full ad copy + image OCR

Under maintenance

Every ad an advertiser runs on Google, with the real copy: headline, body, CTA, display and landing URLs, plus {KeyWord:...} templates and run dates. Image ads are read by a vision model, not Tesseract. Political mode adds spend and impressions. Search by domain, brand or ID. No login.

Pricing

from $0.80 / 1,000 ad results

Rating

0.0

(0)

Developer

Hyperbach

Hyperbach

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

3

Monthly active users

5 days ago

Last modified

Share

Every ad a company is running on Google — with the actual ad copy, including the words baked into image creatives, and for political ads, what it cost. Headline, body text, display URL, call to action, run dates and the advertiser's own {KeyWord:...} insertion templates, for any advertiser in any country. Most Ads Transparency scrapers hand you an image thumbnail and a preview link; this one returns the words — and where the words are pixels, a vision model reads them out. Proxies are handled for you: no proxy to buy, configure or pay for, even on an advertiser with tens of thousands of ads.

A Google display ad on the left — the offer set in artwork, angled and outlined over a photograph — and on the right the structured fields this Actor returns for it, including ad_ocr_text read out of the pixels

Why this scraper, not the other Ads Transparency actors

  • The ad copy, and more of it. Google returns text and responsive ads as a preview URL rather than as text. Most actors ship that URL and stop: measured 2026-08-13, the category leader returns no text field at all, and one free actor returned ad text on 0 of 14 text ads while declaring the field. One competitor does extract copy — head-to-head on the same 20 monday.com creatives, it returned copy on 3 and this actor on 7.
  • We manage the proxies. You do not. Google throttles this source per IP after roughly 2,400 records, and only a fresh exit recovers — which is why most scrapers in this category either hand you a short dataset or tell you to go and buy a rotating proxy first. This Actor carries its own and switches to it the moment a request is blocked, so a 17,838-ad advertiser comes back complete. There is no proxy input to configure, no proxy bill of your own, and nothing to get wrong.
  • Image ads read by a vision model, not a 1990s OCR engine. On a typical consumer advertiser most creatives are pure images with no text field anywhere — the headline and the offer exist only as pixels. Switch on ocrImageAds and they come back as text. It uses an OpenAI vision model rather than classical OCR, and on stylised display creatives that is worth 16% more words recovered (646 vs 557 over 27 real ads, measured 2026-08-14): Tesseract returned TEMY BNG SALE where the ad says TEMU BIG SALE, SU gift for $0 gift, and Estagao de Energia Portatil for Estação de Energia Portátil, while missing 90% OFF CLEARANCE and SHOP NOW completely. Ad artwork — text over photography, letter-spaced, accented — is the case classical OCR is worst at. No key to paste and no separate OpenAI bill: model usage is included in the per-image fee.
  • The {KeyWord:...} insertion templates. A search ad headline is often a template like {KeyWord:Nike Air Max 95}, which is the advertiser's own targeting logic written down: the keywords they bid on and the phrasing they swap in. You get the raw template, not the rendered guess — no other actor in this category exposes the field at all.
  • Run dates, so you can tell what works. Every ad carries when it first ran, when it last ran, and how many days it has been live. An ad running unchanged for 300 days is an ad that converts — nobody funds a loser that long. This is the fastest read on which of a competitor's messages actually earn their budget.
  • Political ads with spend and reach. Switch on politicalAds and election ads come back carrying what commercial ads never do: how much the advertiser spent on each creative and how many times it was shown, as the ranges Google publishes — plus the advertiser's verified identity. Campaign spending, per creative, without a FOIA request.
  • Location and sitelink extensions, when the ad carries them — store names, addresses, cities, and categories attached to the creative.
  • By domain, by brand, or by exact advertiser. One brand often advertises through several verified entities (Nike runs as both Nike Retail BV and Nike, Inc.); a domain search sweeps all of them, and resultType: advertisers lists them so you can see who you are actually looking at.
  • Filters that do not cost you rows you did not want. Date range, ad format, and an onlyAdsWithCopy switch that skips creatives carrying no text — skipped records are never stored and never charged for, so you are not paying per row for image ads when you came for copy.
  • Monitor a competitor and pay only for what changed. Set onlyNewAds with a stateStoreName and each run skips every creative earlier runs already delivered — not fetched, not returned, not charged. Measured: a first run returned 313 ads, the repeat returned 0.
  • It pulls the whole advertiser, and you do not need to bring a proxy. There is no depth cap: a 17,838-ad advertiser comes back complete. This source throttles per IP after roughly 2,400 records, and a rotating exit is the only thing that recovers from it — so this Actor carries one. Most scrapers in this category hand you a short dataset at that point, or tell you to go buy a proxy first. You can still set proxyUrl to use your own. And if the source cuts a search off anyway, the run reports PARTIAL rather than passing a truncated dataset off as a full one: a short result from a quiet advertiser and a short result from a cut-off crawl are different things, and you can tell them apart.

Who it's for

  • Performance marketers & agencies — read a competitor's live ad copy and the keywords behind it, then pitch or counter it — with the run dates showing which messages have survived.
  • Founders sizing up a market — see who is paying to acquire customers in a niche, how long their ads have run, and exactly how they position — evidence of a market with money in it, before you spend any.
  • Copywriters & creative strategists — a corpus of ad copy that is proven in market, sorted by how long it stayed up, instead of swipe files of ads nobody knows performed.
  • Journalists, researchers & campaign teams — election ads with the money attached — what each creative cost, how far it reached, and which committee paid for it.
  • Brand & competitive-intel teams — monitor a competitor's whole ad footprint per country, including which creatives just started and which just stopped.

Quick start

One competitor's ads

{
"domains": [
"monday.com"
],
"region": "US"
}

A whole brand, all its advertiser entities

{
"searchTerms": [
"Nike"
],
"region": "GB",
"maxAds": 200,
"maxAdvertisersPerSearchTerm": 3
}

Metadata only, faster

{
"domains": [
"asana.com"
],
"region": "US",
"includeAdCopy": false
}

Only ads with copy, since July

{
"domains": [
"monday.com"
],
"region": "US",
"onlyAdsWithCopy": true,
"startDate": "2026-07-01"
}

Their YouTube ads only

{
"domains": [
"monday.com"
],
"region": "US",
"platforms": [
"youtube"
]
}

Weekly monitor — only new ads

{
"domains": [
"monday.com"
],
"region": "US",
"onlyNewAds": true,
"stateStoreName": "ads-monday-us"
}

Political ads with spend and reach

{
"searchTerms": [
"for Congress"
],
"region": "US",
"politicalAds": true,
"maxAds": 200
}

Which advertisers does a brand run under

{
"searchTerms": [
"Nike"
],
"region": "US",
"resultType": "advertisers"
}

Output

One record per ad creative:

fieldmeaning
advertiser_nameThe verified advertiser's name as Google publishes it.
advertiser_idGoogle's stable identifier for the advertiser (AR...). Join on this across runs and regions.
creative_idGoogle's stable identifier for this ad creative (CR...). Deduplicate on this.
ad_formattext for search and responsive ads, image for display creatives, video for video ads. Google returns text and video ads identically, so video is only distinguished when includeAdCopy is on — with it off, video ads are labelled text.
ad_surfaceWhich Google surface the ad ran on — search, shopping, youtube — read from the creative's own shape. Needs the ad-copy fetch on; null when the creative was not opened.
headlineThe ad's headline, as written by the advertiser — including any {KeyWord:...} insertion template. Null on pure image and video creatives, which carry no text component.
body_textThe ad's body copy, as written by the advertiser.
ad_ocr_textText read out of an image creative, in reading order — the headline and offer that live in the pixels and appear in no text field. Present only when ocrImageAds is on and the image actually carried words.
headlinesEvery headline variant on the creative. Responsive ads carry several and Google rotates them; the primary headline is the first of these.
descriptionsEvery body-copy variant on the creative, for the same reason as headlines.
display_urlThe display URL shown in the ad (the domain the ad presents itself as).
destination_urlThe landing page the ad actually clicks through to, including its campaign path — the page they are spending money to send traffic to, not just the domain they display.
ctaThe ad's call-to-action button text, as written — INSTALL, Sign up, Jetzt buchen. Present on the display, app and video creatives that carry one; measured at 14 of 48 creatives with copy across seven advertisers. Search ads have none — their button is the headline.
keyword_templatesThe advertiser's raw keyword-insertion values, pulled out of {KeyWord:...} in the headline and body — the terms they bid on and swap into the ad. No other actor in this category exposes this field.
extensionsLocation and sitelink extensions attached to the creative, when present — store name, address, city, postcode, country, and category.
first_shownThe date this creative was first shown, as Google reports it.
last_shownThe date this creative was last shown. A last-shown date in the past means the ad has stopped running.
days_shownHow many days the creative has been running. The single best public proxy for whether an ad converts — long-lived ads are ads someone keeps paying for.
impressions_maxUpper bound of how many times the creative was shown. Political ads only.
impressions_minLower bound of how many times the creative was shown. Political ads only.
spend_currencyCurrency of the spend range, e.g. USD. Political ads only.
spend_maxUpper bound of what the advertiser spent on this creative. Political ads only.
spend_minLower bound of what the advertiser spent on this creative. Political ads only — Google publishes spend as a range, never an exact figure.
image_urlThe creative's image, for display ads.
image_widthImage width in pixels.
image_heightImage height in pixels.
preview_urlGoogle's own rendered preview of the creative. This is the field competing actors return instead of the ad copy.
target_domainThe domain the search matched this creative on. Present when you search by domain, so you can tell which of several domains in one run produced a row.
regionsCountries the creative declares it ran in. Google publishes this for political advertisers, where disclosure is mandatory; commercial ads usually leave it empty.
regionThe country the ads were searched in, as a two-letter code.
ad_urlThe creative's page in Google's Ads Transparency Center, for verification by hand.
advertiser_countryThe advertiser's country of registration, as Google verified it. Only on advertisers records.
advertiser_ad_countHow many ads this advertiser has published in total, as the source counts them. Advertiser results are sorted by it, because the source ranks matches by name similarity — a search for a big brand otherwise leads with tiny lookalike accounts.
advertiser_verifiedWhether Google has verified this advertiser's identity. Only on advertisers records.
matched_queryThe domain or search term that matched this advertiser. Only on advertisers records.
advertiser_urlThe advertiser's page in Google's Ads Transparency Center. Only on advertisers records.
rawThe source's untouched record for this creative, present only when includeRawData is on.
advertiser_legal_nameThe advertiser's registered legal name, as verified by Google. Political advertiser records only.
advertiser_fec_idThe committee's FEC identifier, e.g. C00786657 — the key that joins this advertiser to US campaign-finance filings. Political advertiser records only.
advertiser_officeOffice sought, as filed: H House, S Senate, P President. Political advertiser records only.
advertiser_districtDistrict contested, e.g. SC-07. Political advertiser records only.
advertiser_ads_minLower bound of how many ads this advertiser has run in total. Political advertiser records only.
advertiser_ads_maxUpper bound of how many ads this advertiser has run in total.
advertiser_impressions_minLower bound of how many times this advertiser's ads were shown in total. Political advertiser records only.
advertiser_impressions_maxUpper bound of how many times this advertiser's ads were shown in total.
advertiser_spend_totalTotal spent by this advertiser on Google ads, to the dollar — not a range. Read from the same statistics the Ads Transparency Centre shows on its Insights tab. Political advertiser records only.
advertiser_spend_currencyCurrency of advertiser_spend_total, e.g. USD.
advertiser_ads_totalExact number of ads this advertiser has run, as the statistics endpoint reports it — the advertiser card only carries a range.
spend_by_dayDaily spend history for the advertiser — one row per day with date, spend_share and spend in the advertiser's currency. Hundreds of days for an established campaign. Political advertiser records only.
spend_by_regionWhere the money went — one row per region with the place region named (South Carolina), its region_canonical and region_country, alongside spend_share, spend, and ads_share, the share of the advertiser's ads that ran there. Note ads_share does not sum to 1: one ad runs in many regions. Political advertiser records only.
spend_by_formatSpend split by creative format, with the share of ads in each. Political advertiser records only.
record_typeremoved_ad on rows from the Europe removal feed. Absent on ordinary ad records.
policy_decided_atWhen Google decided to remove the ad. Removal-feed rows only.
removal_reasonThe headline reason the ad was removed, e.g. Misrepresentation or Account suspension — the first named violation on the record. Removal-feed rows only.
violationsWhat the ad was removed for: one entry per violation with the named policy and policy_categoryMisrepresentation / PROHIBITED PRACTICES — alongside Google's raw codes. Google publishes the taxonomy as numbers only; the names here were derived by pairing 280 feed rows against the labels the Ads Transparency Centre renders for those same rows. A code outside the derived set keeps its number and a null name rather than a guess. Removal-feed rows only.

Example record:

{
"advertiser_name": "monday.com LTD",
"advertiser_id": "AR15972262369074085889",
"creative_id": "CR11041510797959233537",
"ad_format": "video",
"ad_surface": null,
"headline": "Turn talk into action",
"body_text": "Let AI agents handle project setup so you can focus on delivery. See how on monday.com.",
"ad_ocr_text": null,
"headlines": [
"Turn talk into action"
],
"descriptions": [
"Let AI agents handle project setup so you can focus on delivery. See how on monday.com."
],
"display_url": "monday.com",
"destination_url": "https://monday.com/ap/ai-departments/project-management",
"cta": null,
"keyword_templates": [],
"extensions": [],
"first_shown": "2026-06-02",
"last_shown": "2026-08-13",
"days_shown": 73,
"impressions_max": null,
"impressions_min": null,
"spend_currency": null,
"spend_max": null,
"spend_min": null,
"image_url": "https://tpc.googlesyndication.com/simgad/13276690459228525322",
"image_width": null,
"image_height": null,
"preview_url": "https://displayads-formats.googleusercontent.com/ads/preview/content.js?client=ads-integrity-transparency&obfuscatedCustomerId=3638868375&creativeId=811470747742&uiFeatures=12,54&adGroupId=184108759808&versionId=2&sig=ACiVB_w902w6auG7R08K04f2CVhR-MrtMQ&htmlParentId=fletch-render-4565625868432914769&responseCallback=fletchCallback4565625868432914769",
"target_domain": null,
"regions": null,
"region": "US",
"ad_url": "https://adstransparency.google.com/advertiser/AR15972262369074085889/creative/CR11041510797959233537?region=US",
"advertiser_country": null,
"advertiser_ad_count": null,
"advertiser_verified": null,
"matched_query": null,
"advertiser_url": null,
"raw": null,
"advertiser_legal_name": null,
"advertiser_fec_id": null,
"advertiser_office": null,
"advertiser_district": null,
"advertiser_ads_min": null,
"advertiser_ads_max": null,
"advertiser_impressions_min": null,
"advertiser_impressions_max": null,
"advertiser_spend_total": null,
"advertiser_spend_currency": null,
"advertiser_ads_total": null,
"spend_by_day": null,
"spend_by_region": null,
"spend_by_format": null,
"record_type": null,
"policy_decided_at": null,
"removal_reason": null,
"violations": null
}

Pricing

Pay only for what a run actually returns, with no start fee. Prices are per 1,000 and fall with your Apify plan:

FREEBRONZESILVERGOLDPLATINUMDIAMOND
Ad result$1.20$1.00$0.90$0.80$0.75$0.70
Ad copy, when the creative carried any+$1.30+$1.15+$1.05+$0.95+$0.90+$0.85
Political spend & reach, when published+$1.50+$1.30+$1.15+$1.00+$0.95+$0.90
Image text read (OCR), model usage included+$1.00+$1.00+$1.00+$1.00+$1.00+$1.00
Advertiser record$2.00$1.70$1.50$1.30$1.20$1.10

So ordinary ads with copy run $2.50 per 1,000 on a free plan and $1.55 on the top tier; metadata alone is $1.20 falling to $0.70. OCR is flat at every tier because it is the one line with a real per-image cost behind it — you are not billed separately by OpenAI, and you paste no key.

Each fee is charged per record that actually carries the thing. Image creatives contain no text and are never billed the copy fee. Ads where Google published no spend are never billed the political fee. Set onlyAdsWithCopy and text-free ads are not returned or billed at all.

Usage patterns

  • Pull a competitor's ad copy — Pass their domain and a region. You get every ad they run there, each with its headline, body text, display URL, and how long it has been running.
  • Find the messages that survive — Sort the results by days_shown. The ads at the top have been paid for the longest, which is the strongest public signal that they convert.
  • Extract the keyword strategy — Read keyword_templates across an advertiser's ads to see the terms they bid on and how they phrase their offer around each one.
  • Track political spending — Set politicalAds and pass a committee or candidate advertiser. Every ad comes back with its spend range and how many times it was shown, so you can rank a campaign's creatives by budget.
  • Compare a market — Run several competitor domains in one go with maxAdsPerTarget set, so one prolific advertiser cannot eat the whole budget and leave the others empty.
  • Find who a brand advertises as — Set resultType to advertisers and pass a brand name. You get every verified advertiser entity matching it, with country and verification status, before you spend anything pulling ads.
  • Watch a competitor weekly — Schedule the same input with onlyNewAds and a stateStoreName. Every run returns only creatives you have not been given before, so a weekly watch costs a handful of ads instead of the whole advertiser.
  • Only what changed recently — Set startDate to keep ads whose run overlaps that date or later — new creatives, plus the long-running ones still live.

Input configuration

fieldtypedefaultwhat it does
domainsarray[]Domains to pull ads for, e.g. nike.com. Returns every verified advertiser matching that domain — a brand often runs under several (Nike advertises as both Nike Retail BV and Nike, Inc.).
searchTermsarray[]Brand or company name, e.g. Nike. Resolved to the matching verified advertisers first, then their ads are pulled — the ad search itself matches domains, not names, so a bare name would otherwise return nothing. Use maxAdvertisersPerSearchTerm to control how many matches are followed.
advertiserIdsarray[]Exact advertiser IDs, e.g. AR18378488041124659201 — the AR... value in an advertiser's Ads Transparency Center URL. Use this when you want one specific advertiser and nothing else.
regionstring"US"Two-letter country code for the country the ads were shown in, e.g. US, GB, DE, ES, IN. Ads are published per country: the same advertiser returns different creatives in different regions. Use anywhere to search every country at once — the same thing region=anywhere does in a Transparency Center URL. anywhere covers scraping ads by domain, advertiser id or URL; searchTerms, resultType: advertisers and politicalAds need a real country, because Google's lookup and stats endpoints return nothing without one.
resultTypeads / advertisers"ads"ads returns one record per ad creative. advertisers returns one record per verified advertiser matching your domains or search terms — use it to discover which advertiser entities a brand runs under before pulling their ads.
startDatestringYYYY-MM-DD. Keeps ads whose run overlaps this date or later — an ad that started years ago and is still running counts, because it is still running.
endDatestringYYYY-MM-DD. Keeps ads whose run overlaps this date or earlier.
adFormatsarray[]Keep only these formats. Empty means all. Google returns text and video ads identically, so selecting either turns on the ad-copy fetch — that is the only thing that tells them apart.
onlyAdsWithCopybooleanfalseSkip ads that carry no text at all — image creatives, and the occasional preview the source refuses to serve. Records that are skipped are never stored and never charged for, so you only pay for rows that carry the copy.
includeAdCopybooleantrueFollow each ad's creative preview and extract the real headline, body text, display URL and the advertiser's {KeyWord:...} insertion templates. Turn off for a faster, metadata-only run.
maxAdsinteger0Stop after this many ads in total, across every search. 0 means no limit.
maxAdsPerTargetinteger0Cap each domain, search term, or advertiser ID separately. Without this, one prolific advertiser can consume the whole maxAds budget and the searches after it return nothing. 0 means no per-search cap.
adCopyConcurrencyinteger4How many creative previews to fetch in parallel. Raise for speed, lower if you see throttling.
requestDelaySecsnumber0.3Seconds to wait between result pages. The source tolerates a steady pace far better than a burst.
maxAdvertisersPerSearchTerminteger5How many matching advertisers to follow for each brand search term. A common name like Nike matches 150+ advertisers, most of them unrelated small businesses; the default takes the closest few.
startUrlsarray[]Paste Ads Transparency Center URLs — an advertiser page (.../advertiser/AR...) or a single creative (.../advertiser/AR.../creative/CR...). A creative URL narrows the run to that creative, and a region in the URL is used unless you set one explicitly.
platformsarray[]Keep only ads shown on these Google surfaces. Empty means all. search and shopping share one filter at the source, so separating those two also needs the ad-copy fetch on.
creativeIdsarray[]Return only these creatives (CR...). Pair with advertiserIds or a creative URL in startUrls: the source has no by-creative lookup, so the advertiser's ads are paged until every requested creative is found.
onlyNewAdsbooleanfalseSkip creatives delivered by previous runs that used the same stateStoreName. Skipped ads are never fetched, never returned and never charged — a weekly monitoring run pays only for what actually changed.
stateStoreNamestringNamed key-value store holding the creative IDs already delivered, so onlyNewAds can tell new from old across runs. Use one name per thing you monitor, e.g. ads-monday-us.
resumeCursorstringContinue paging from where an earlier run stopped. Paste the RESUME_CURSOR value from that run's key-value store. It is Google's own paging position — not a credential, and it grants no access to anything.
includeRawDatabooleanfalseAdd the source's own untouched record to each row as raw, for callers who would rather map the fields themselves.
politicalAdsbooleanfalseReturn political and election ads instead of ordinary ones. These carry what commercial ads never do: how much was spent on each creative and how many times it was shown, both as the ranges Google publishes. Note this is a filter — with it on, only political ads come back.
cacheStoreNamestring"gads-cache"Named key-value store holding ad copy already extracted, so the same creative is never fetched twice — across your runs and over time. Ad creatives never change once published, so cached copy is served for ever; campaign statistics expire on the TTL below. Clear the field to disable caching.
cacheTtlHoursinteger24How long slow-moving entries stay valid — campaign statistics and advertiser lookups. Extracted ad copy ignores this and is kept for ever, because a creative's content cannot change.
removedAdsbooleanfalseReturn Google's Europe-wide feed of ads it has taken down, newest first, with the policy decision date and what each ad ran for before removal. This is a single global feed: advertiser, domain and region filters do not apply to it.
ocrImageAdsbooleanfalseImage creatives carry their words in the pixels and have no text field at all — on a typical advertiser they are most of the result set. Turn this on to read them with a vision model. Adds roughly two seconds per image, and is charged only for images that actually yielded text.
openaiApiKeystringOptional. The Actor uses its own model access by default and bills you a flat fee per image read. Supply your own OpenAI key only if you would rather the model usage went to your account.
ocrConcurrencyinteger12How many image creatives to read at once when ocrImageAds is on. Separate from adCopyConcurrency, which paces requests to Google: OCR calls a different service, and it is network-bound, so it scales with concurrency (measured 0.6 to 3.9 images/second going from 1 to 16). Lower it only if you hit your own provider's rate limit.

FAQ

How is this different from the other Google Ads Transparency scrapers?

They return metadata — creative IDs, dates, an image thumbnail, and a preview URL. This one opens the preview and returns the actual text of the ad: headline, body, display URL, and the raw {KeyWord:...} templates. If you only need IDs and dates, the cheaper actors are fine.

Which countries can I search?

Any country the Ads Transparency Center covers — pass a two-letter code such as US, GB, DE, ES, IN — or anywhere to search every country at once, the same thing region=anywhere does in a Transparency Center URL. Ads are published per country, so the same advertiser returns different creatives in different regions: a GB locksmith returns 11 ads under GB, none under US, and the same 11 under anywhere. anywhere covers scraping ads by domain, advertiser id or URL; searchTerms, resultType: advertisers and politicalAds need a real country, because Google's advertiser-lookup and stats endpoints return nothing without one.

Some ads show in the Transparency Center but not in my results — why?

Four reasons, in the order they actually occur:

  1. You are signed in and the Actor is not. Google serves some ads only to a signed-in account. This Actor runs anonymously — no Google account, nothing to get your account flagged — so those ads are not in the output. Open the same page in an incognito window: what you see there is what you get here.
  2. Google's count is a range, not a number. "~4K ads" means somewhere between 3,000 and 4,000. Getting 3,015 back is the count being right, not the scrape being short.
  3. Region. Ads are published per country. An advertiser with 200 ads in Germany may have none in the US. Use anywhere if you do not care which country.
  4. The source cut the run off. Sustained paging gets throttled at roughly 2,400 ads on a single IP. When that happens the run reports PARTIAL and names the searches it could not finish — it never hands you a short dataset labelled as complete. Set proxyUrl to a rotating proxy to page past it.

Do I get image and video ads too?

Yes. Image ads come with the image URL and its dimensions; video ads are identified as such and carry their copy plus the companion banner. Note that pure image creatives contain no text anywhere — on a typical consumer advertiser they are the majority of ads, so if you only want rows with copy, set onlyAdsWithCopy and you will not be charged for the rest.

How good is the image-ad OCR, really?

It is an OpenAI vision model (gpt-4.1-mini), not Tesseract or PaddleOCR, and the difference shows on exactly the creatives you would buy OCR for.

Measured 2026-08-14 on 27 real display creatives, both engines over identical bytes: 646 words recovered against Tesseract's 557. On plain search ads rendered as images the two tie — that is clean black text on white, which classical OCR handles fine. The gap opens on ad artwork: text over photography, letter-spaced, accented, or part of the design. Tesseract read TEMY BNG SALE where the ad says TEMU BIG SALE, SU gift for $0 gift, Estagao de Energia Portatil for Estação de Energia Portátil, and missed 90% OFF CLEARANCE and SHOP NOW outright.

Honest trade-off: it is slower per image than a local binary (about 1.5s against 0.26s), because the request leaves the machine. You are paying for the read being right, and the fee includes the model usage — no key to paste, no second bill.

What do I get for political ads that I do not get otherwise?

Spend and reach. Each political creative carries the range Google published — for example USD 200-300 spent and shown 0-1,000 times — alongside the usual dates and copy. Note politicalAds is a filter: with it on, only political ads are returned, so run it separately from a commercial pull. Many political creatives are images and carry no text, and the copy fee is not charged on those.

Is this the whole history of an advertiser's ads?

It is everything the Ads Transparency Center currently publishes for that advertiser in that region, including ads that have stopped running — first_shown and last_shown tell you when each ran. Google decides what stays published; this actor does not add history of its own.

Do I need a login or an API key for Google?

No login and no API key — the Ads Transparency Center is public. You also do not need a proxy: Google throttles this source per IP after roughly 2,400 ads, and this Actor carries its own rotating exit and escalates to it automatically the moment a request is blocked, so a 17,838-ad advertiser comes back complete and you configure nothing. Runs that never reach the limit never touch a proxy at all. If the source cuts a search off anyway, the run reports PARTIAL and names what it could not finish, rather than handing you a short dataset that looks complete.

Integration

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('hyperbach/google-ads-transparency-scraper').call({"domains": ["monday.com"], "region": "US"});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Python

from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('hyperbach/google-ads-transparency-scraper').call(run_input={'domains': ['monday.com'], 'region': 'US'})
items = client.dataset(run['defaultDatasetId']).list_items().items

CLI

$apify call hyperbach/google-ads-transparency-scraper --input '{"domains": ["monday.com"], "region": "US"}'

REST

curl -X POST "https://api.apify.com/v2/acts/hyperbach~google-ads-transparency-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H 'Content-Type: application/json' -d '{"domains": ["monday.com"], "region": "US"}'

Support

support@hyperbach.com

This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.