Google Ads Transparency scraper artworkSearch, YouTube & Display

Google Ads Transparency Scraper.

Look up an advertiser and collect its public ads across Google. You can compare formats, see when creatives appeared, and check how the messaging changes between markets.

Run on Apify

Ways to use this scraper.

Try these examples for marketing, growth and competitor research.

01

Compare competitors' channel choices

Before a SaaS launch, look up three competing domains. Review their creative formats and see which messages appear in search, display and video. Use the examples to plan your own channel tests.

Keep a competitor creative inventory with notes on the channels you want to investigate.

02

Compare advertising in two markets

If you're researching a retail launch, follow advertiser activity in two target countries. Use first- and last-shown dates to check when creatives appeared and how the copy differs.

Make a country comparison with links to the public ad records.

03

Save references for a video or display campaign

For a small group of advertisers, turn on extra details and save variant URLs. Resolve public YouTube IDs where they're available, then review the assets before starting production.

Organize the assets by format so your team can find campaign references.

FROM FIRST RUN TO REPEATABLE WORKFLOW

Your first run, step by step.

  1. Open the Actor on Apify, select its Input tab and switch to the JSON editor if you want to paste a configuration.
  2. Paste the example into the JSON editor and replace nike.com with the advertiser’s website. Review the resolved advertiser in the first results; a domain can still fall back to a brand-name search.
  3. Choose one region and cap the run at 50 unique ads. Leave fetchAdDetails and resolveMedia false until you know whether the listing fields are enough. Both switches can add requests for every ad.
  4. Start the run and watch the log. Check which targets and filters were actually read before assuming an empty result means nothing exists.
  5. Open Storage → Dataset, inspect several records and export JSON for nested data or CSV for a first spreadsheet review.
First-run configuration
{
  "domains": ["nike.com"],
  "regions": ["GB"],
  "platform": "all",
  "maxAds": 50,
  "fetchAdDetails": false,
  "resolveMedia": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}

Paste this into the Actor’s JSON input editor. Replace the example targets with yours before running.

Check the current input form on Apify

Choose how to search.

Names, domains, advertiser IDs and Transparency Center URLs can all identify an advertiser. Use an ID when a brand has several legal entities or a name search keeps choosing the wrong one.

Search methodWhen to use itWhat changes
Website domainsWhen to use itYou have a competitor watchlist.What changesVerified advertiser domains such as nike.com. More precise than a loose brand name. An unmatched domain can fall back to a brand-name lookup, so inspect the resolved advertiser.
Advertiser or brand nameWhen to use itYou want to find relevant results before choosing specific targets.What changesSearch brand or company names. The Actor also checks the brand’s domain and chooses a matching advertiser. Inspect the resolved identity; use an AR ID to pin an exact entity.
Advertiser IDsWhen to use itYou know the exact entity you want to collect.What changesAR advertiser IDs from Transparency Center URLs. These avoid ambiguous name resolution and are the most reliable way to track the same legal entity over time.
Ad Library URLsWhen to use itYou already configured the search on the source website.What changesPaste advertiser URLs from Google’s Transparency Center. Each URL carries its own region and platform; global settings only fill missing filters.

The difference that matters

Keeps ads whose last-shown date is on or after this date. Filtering happens after collection because Google’s endpoint has no date filter; it does not guarantee fewer requests.

Compare the related scraper

Every input, explained.

Use the exact field names below in JSON. In Apify’s form, enter list items separately, choose filters, and keep numbers and booleans in their proper types.

Default and prefill are different. A default applies when you omit a setting; a prefill is an example already entered in Apify’s form. Review prefilled targets and limits before every run. Some settings have no schema default. You still need to supply at least one supported target.

Targets and search inputs7
searchTerms
ListForm prefill: ["Nike"]

Search brand or company names. The Actor also checks the brand’s domain and chooses a matching advertiser. Inspect the resolved identity; use an AR ID to pin an exact entity.

domains
List

Verified advertiser domains such as nike.com. More precise than a loose brand name. An unmatched domain can fall back to a brand-name lookup, so inspect the resolved advertiser.

domain
Text

One domain instead of a domains list. Use the bare domain; paths on the website do not narrow the advertiser’s ads.

advertiserIds
List

AR advertiser IDs from Transparency Center URLs. These avoid ambiguous name resolution and are the most reliable way to track the same legal entity over time.

advertiserId
Text

The single-advertiser version of advertiserIds. Copy the AR value from the advertiser’s Transparency Center URL, not a creative ID.

transparencyUrls
List

Paste advertiser URLs from Google’s Transparency Center. Each URL carries its own region and platform; global settings only fill missing filters.

transparencyUrl
Text

One advertiser URL, with the same precedence as transparencyUrls. A region embedded in the URL overrides a conflicting global region.

Markets, dates and filters5
regions
List

Several country codes or names create separate advertiser-region jobs. Results overlap and are deduplicated by creative_id. Empty means all served regions; unsupported countries are skipped.

region
Text

One country, used only when the regions list is empty. Prefer regions when comparing several markets.

platform
TextDefault: all

Restricts the Google advertising surface. Choose search, youtube, display, shopping, maps or play, or all. Ads can appear on several surfaces, so platform totals can overlap.

Suggested JSON values
all search youtube display shopping maps play
minDate
Text

Keeps ads whose last-shown date is on or after this date. Filtering happens after collection because Google’s endpoint has no date filter; it does not guarantee fewer requests.

maxDate
Text

Keeps ads first shown on or before this date. Together with minDate, it selects ads whose delivery overlaps your window. Use YYYY-MM-DD for predictable input.

Limits, details and proxies8
proxyConfiguration
ObjectDefault: {"useApifyProxy":true}Form prefill: {"useApifyProxy":true}

Apify Proxy is recommended; datacenter is usually sufficient. Residential is not required for this Actor. A rejected proxy configuration can fall back to the account’s default proxy.

maxConcurrency
IntegerDefault: 4

1-10 advertiser-region jobs in parallel. Increasing it helps with multiple advertisers or regions; one advertiser in one region still paginates sequentially.

maxAds
IntegerForm prefill: 1000

A hard cap on unique ads across the whole run, including all targets and markets. Start with 50. Leaving it empty removes this cap; a broad search can then become much larger.

maxPages
Integer

Page cap for each advertiser-region job. A page contains up to pageSize ads, at most 100. This is a testing limit, not a global result cap.

fetchAdDetails
True or falseDefault: false

Adds region breakdowns, regional delivery dates and creative variants. It requires one extra request per ad; enable it only for research that needs these fields.

resolveMedia
True or falseDefault: false

Makes extra requests to resolve public YouTube video IDs from previews. It cannot create a public video URL for display-video ads that do not have one.

pageSize
IntegerDefault: 100

1-100 ads per request. Values above 100 are clamped because Google rejects larger batches. Keep 100 unless debugging a particular response.

delayMs
IntegerDefault: 500

Pause between page requests, in milliseconds. Increase it when the source throttles you; reducing it does not remove network delays or the source’s rate limits.

Advanced settings and recovery6
raw
True or falseDefault: false

Returns the source structure rather than the normalized presentation. Keep false for consistent analysis columns; use true when you need the source payload for debugging or your own transformations.

proxyRotations
IntegerDefault: 3

Retries refused work with a new proxy session. More retries can recover temporary blocks but add time and traffic. Keep the default until the log shows a reason to change it.

resume
True or falseDefault: true

Saves progress about every 30 seconds so an Apify restart or migration can continue the current run. Leave it on for normal use.

continueFromLastRun
True or falseDefault: false

Continues unfinished work from the previous run with matching input. Earlier results remain in that run’s dataset. Keep false for a fresh collection or a recurring snapshot.

impersonate
TextDefault: chrome131

The browser identity used for requests. Keep the Actor’s default unless you are diagnosing immediate blocks. It changes the request fingerprint, not the data you ask for.

proxySessionId
Text

Pins a proxy session for debugging. Leave empty for routine collection. Parallel jobs need their own sessions, so this setting is ignored when parallelism prevents a single fixed session.

This reference follows the Actor’s published input fields. Check the live form before changing a production workflow. Check the current input form on Apify.

Configurations you can copy.

Each example is a separate run. Start small, inspect the results, then increase coverage. Update the targets, countries and dates to match your question.

Compare two brands in two markets

Two domains and two regions produce four advertiser-region jobs. The 150-ad cap applies to the combined, deduplicated dataset. It does not reserve an equal sample for every brand or country.

Compare two brands in two markets
{
  "domains": ["nike.com", "adidas.com"],
  "regions": ["GB", "FR"],
  "maxAds": 150,
  "fetchAdDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}

Build a YouTube creative shortlist

Filter to YouTube and enable resolveMedia to try to resolve video IDs and URLs. Review the returned media fields before giving Claude links to summarize; some creatives still have no directly accessible video.

Build a YouTube creative shortlist
{
  "domains": ["nike.com"],
  "regions": ["GB"],
  "platform": "youtube",
  "maxAds": 50,
  "resolveMedia": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}

Collect a dated regional sample

Add detailed fields and a delivery window for Germany. Dates are checked after ads are fetched, so a narrow window does not guarantee a cheap run. Replace the example dates and start with a small cap.

Collect a dated regional sample
{
  "domains": ["nike.com"],
  "regions": ["DE"],
  "minDate": "2026-09-01",
  "maxDate": "2026-09-30",
  "maxAds": 50,
  "fetchAdDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}

Run, check, export, repeat.

Keep advertiser and creative IDs with region, platform and the collection date. Detail and media switches enrich the same records rather than creating a separate performance dataset. Use Sheets for a creative review, or BigQuery and dbt for deduplicated history. The source does not provide spend, ROAS or conversions.

  1. Check the dataset and the run’s SUMMARY record. Compare the number collected with your cap, inspect failed or skipped inputs, and verify a few original source links.
  2. Keep the original IDs and add collected_at and run_id when saving results. Export CSV for flat columns; retain JSON when arrays or nested details matter.
  3. Save the tested configuration as an Apify Task and schedule it. For repeated snapshots, leave continueFromLastRun false. Deduplicate new records by source ID while retaining each observation date.
  4. In Make or n8n, wait for a successful run, fetch its dataset and map fields into Sheets or your warehouse. Send records to Looker Studio through a reporting table; use dbt to flatten and test warehouse models.
  5. The same JSON works with Apify’s Actor API. In Claude with Apify MCP, name this Actor, ask it to inspect the live schema, and give explicit targets, markets and result limits before it runs.

Resume is not a fresh snapshot

resume protects the current run if Apify restarts it. continueFromLastRun continues an earlier run with the same configuration; earlier records stay in the earlier dataset. Combine both datasets for the complete collection, and raise a previously reached result cap when continuing. Start fresh when you want to see what changed today.

Follow the Sheets, Claude, Looker and BigQuery setup guides
Run this Actor from the API

Save one configuration above as input.json. Set APIFY_TOKEN to your Apify API token in your terminal, then send the file as the request body.

Start the run
curl --fail-with-body --request POST \
  --url "https://api.apify.com/v2/actors/jmlp~google-ads-transparency-center-scraper/runs" \
  --header "Authorization: Bearer $APIFY_TOKEN" \
  --header "Content-Type: application/json" \
  --data-binary @input.json

The response contains a run ID and defaultDatasetId, not finished results. Wait for the run to succeed, set DATASET_ID to that dataset ID, then fetch its items. For large datasets, use limit and offset to page through the export.

Fetch the dataset
curl --fail-with-body \
  --url "https://api.apify.com/v2/datasets/$DATASET_ID/items?format=json" \
  --header "Authorization: Bearer $APIFY_TOKEN"

Apify’s run and export API reference
Dataset export options

When the results look wrong.

Change one setting at a time, keep a small cap, and check the run summary before scaling up.

The results belong to the wrong advertiser.

AR advertiser IDs from Transparency Center URLs. These avoid ambiguous name resolution and are the most reliable way to track the same legal entity over time.

Some ads have no direct video URL.

Makes extra requests to resolve public YouTube video IDs from previews. It cannot create a public video URL for display-video ads that do not have one.

Increasing concurrency did not make the run faster.

1-10 advertiser-region jobs in parallel. Increasing it helps with multiple advertisers or regions; one advertiser in one region still paginates sequentially.

The run succeeded but returned nothing

Success means the Actor finished handling the request, not that the source returned data. Check SUMMARY.inputProblem, SUMMARY.problem and the log for missing targets, unsupported filters or refused requests. Test one known target with fewer filters.

Fewer records than expected

Check the global limit, per-search or per-page limits, platform coverage and deduplication. Several searches can find the same record. A source’s headline count can include records the public endpoint does not return. Review unfinished jobs before treating the dataset as complete.

Use the results in your tools.

Google Sheets

Keep creative_id, advertiser_name, format, first_shown, last_shown and preview_url in one sheet. Add a campaign-theme column for your team's notes.

Read the setup
Claude + MCP

Ask Claude to compare creative formats and delivery dates for a small group of advertisers. Request source links and keep its interpretations separate from what the records show.

Read the setup
Looker Studio

Compare formats by advertiser and show when new creative IDs appear. If you collect regions, flatten that array before reporting by market.

Read the setup
BigQuery + dbt

Remove duplicates using creative_id but keep each dated observation. Store regions and variants in child tables so joins don't inflate the creative count.

Read the setup
Copy a prompt for Claude
Prompt for Claude + Apify MCP
Inspect the input schema for jmlp/google-ads-transparency-center-scraper, then collect at most 50 records for nike.com in GB. Summarize available creative formats and delivery dates, cite transparency_url, and identify questions a marketer should investigate. Do not estimate spend or ROAS.

The fields you’ll get.

Keep the collection time and original IDs with your records. You’ll need them to check where a result came from or compare it with a later run.

Before you draw conclusions

Google's transparency data doesn't include competitor conversions or ROAS. The scraper applies date filters after collection, so a narrow date range may not shorten the crawl. Extra ad details and video resolution add requests; enable them when you need them.

creative_id
A stable key for each creative record.
advertiser_id / advertiser_name
Google’s advertiser identity, which can use a legal entity name.
format
Text, image, video or shopping, derived from the payload.
first_shown / last_shown
Reported delivery dates for the creative.
image_url / preview_url
Available creative assets and preview links.
regions / creative_variants
Optional enrichment when fetchAdDetails is enabled.

Common questions.

Does it cover only Google Search ads?

It can collect records across Google advertising surfaces, including Search, YouTube, Display, Shopping and Maps, depending on the selected platform and available public data.

Will a date filter reduce my run cost?

Not necessarily. The source endpoint has no date filter, so the scraper collects pages and filters records afterward. Use maxAds and optional-detail controls to bound the run.

Source and current product details: JMLP’s Google Ads Transparency Actor on Apify.

Other scrapers
you might use.

Let’s talk about
your project.

Tell me what you need to collect or understand. I can help with a custom scraper, a pipeline or the analysis.

Start a project