How to list a brand's ads in the Google Ads Transparency Center
Find the advertiser with Google Ads Transparency advertiser search, then page through its ads with Google advertiser ads. The worked example is 5 calls and costs $0.02; a failed call is not charged.
Updated
The job: you want to see what one brand runs on Google, across Search, YouTube, Display, Shopping, Maps and Play, and when each ad was live. The Transparency Center shows this one ad at a time. Turn the brand's name into Google's advertiser ID, then list its ads page by page. You end with a table of ads, each with its format, preview image, first and last time shown and a link back to the Transparency Center.
No Google account or Ads login is involved. Each call is an HTTPS request with your key.
Step by step
Step 1: find the advertiser ID
Call Google Ads Transparency advertiser search with the brand in query and, optionally, country (an ISO code, US by default). One call returns up to 10 matching advertisers for $0.004, each with:
id: the advertiser ID,ARfollowed by 20 digits.name: the name Google verified. This is often the legal entity that pays, not the brand you know.region: the country it is registered in.ads: the Transparency Center's estimate of how many ads it has.
curl -G "https://api.okdata.online/v1/google/advertisers/search" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'query=Kettle & Pine' \
-d country=US
Several rows with the same name are common: one name can appear under several advertiser IDs, registered in different regions or belonging to unrelated companies. Pick the row whose region and ads estimate fit, and open its url once to check you have the right one. There is no second page; refine the query instead.
Step 2: list the ads
Call Google advertiser ads with either id (from step 1) or domain (the brand's website, such as kettleandpine.com). Give one, not both; both or neither is invalid_params, which is not charged.
idreturns the ads of that one verified advertiser.domainskips step 1 and returns ads that point at the website. That can include other advertisers, such as resellers or agencies promoting the same site, so checkadvertiser.nameon each row.
Two filters narrow the list: country (only ads shown in that country; anywhere when left out) and format (all by default, or text, image, video). One call returns up to 40 ads for $0.004. Each ad has id (the creative ID, CR followed by 20 digits), url, advertiser (id and name), format, the preview in images, first_shown_at and last_shown_at.
curl -G "https://api.okdata.online/v1/google/advertisers/ads/list" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
-d id=AR09284716350029384715 -d country=US -d format=video
For the next page, send page.next_cursor back as cursor, unchanged, until page.has_more is false.
Step 3: in Python
import collections
import csv
import os
import requests
API = "https://api.okdata.online"
HEADERS = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
MAX_PAGES = 4 # each page is one call
def get(path, **params):
body = requests.get(API + path, headers=HEADERS, params=params, timeout=60).json()
if body["code"] != "ok":
raise RuntimeError(f"{body['code']}: {body['message']} (charged: {body['charged']})")
return body
found = get("/v1/google/advertisers/search", query="Kettle & Pine", country="US")["data"]["items"]
advertiser = max(found, key=lambda a: a["ads"] or 0) # check this pick by hand the first time
ads, cursor = [], None
for _ in range(MAX_PAGES):
body = get("/v1/google/advertisers/ads/list", id=advertiser["id"], country="US", format="video", **({"cursor": cursor} if cursor else {}))
ads += body["data"]["items"]
if not body["page"]["has_more"]:
break
cursor = body["page"]["next_cursor"]
with open("google_ads.csv", "w", newline="", encoding="utf-8") as f:
out = csv.writer(f)
out.writerow(["creative_id", "advertiser", "format", "first_shown", "last_shown", "preview", "url"])
for a in ads:
out.writerow([a["id"], a["advertiser"]["name"], a["format"], a["first_shown_at"], a["last_shown_at"], (a["images"] or [""])[0], a["url"]])
by_month = collections.Counter((a["first_shown_at"] or "")[:7] for a in ads)
print(advertiser["name"], len(ads), "ads;", "new per month:", sorted(by_month.items()))
Good to know
- What the list leaves out. Title, landing page, call to action, placements, video files, active flag and reach are null and named in
meta.unavailable.textis usually empty: many ads, text ads included, are shown only as a rendered preview, so the copy sits inside the preview image. A vision model or OCR overimagesreads it back. - No preview for some ads.
imagescan be null when the Transparency Center has no preview for a creative. - No spend or impressions for commercial ads; the Transparency Center does not publish them.
- No network filter. There is no filter for Search, YouTube or Display. Text ads are mostly Search ads and video ads mostly YouTube, so
formatis the closest proxy. - Extras.
view=fulladdsext.domain, the website an ad was matched to. - Retries without paying twice. Send an
Idempotency-Keyheader with each call; the same request with the same key within 24 hours returns the stored answer and no new charge.
For the full export with every gap explained, see exporting a competitor's ads from the Transparency Center. To follow the same brand on Meta and TikTok as well, see competitor ads on three libraries.
What the example costs
One advertiser search for a cookware brand, then four pages of its video ads shown in the US
| Endpoint | Calls | Price | Subtotal |
|---|---|---|---|
| Google Ads Transparency advertiser search | 1 | $0.004 | $0.004 |
| Google advertiser ads | 4 | $0.004 | $0.016 |
| Total | 5 | $0.02 |
Prices in force when this page was built. A failed call costs nothing.
In your AI (MCP)
Connect the MCP server once, then say what you want. The agent finds these endpoints, reads their prices and calls them on your balance.
SayFind the Google Ads Transparency Center advertiser for the brand Kettle & Pine in the US, then list four pages of its video ads shown in the US with format, first and last time shown and preview image. Which months had the most new ads?
What the agent sends to the call tool first
{
"endpoint": "google.advertisers.search",
"params": {
"query": "Stanley"
},
"idempotency_key": "<a new UUID>"
}