LurkAPI
Docs · Google ad details

Google ad details

One ad from Google's Ads Transparency Center: every version of the creative, where it ran and, for political ads, spend and targeting.

1 credit per callFresh within 12 hoursMCP tool: google_ad
GEThttps://api.lurkapi.com/v1/google/ad

Example response

When to use this

Use it after company ads (google_company_ads) to see one ad's versions, the countries it ran in and its landing page. Pass the ad's Transparency Center link as url, or both advertiser_id and creative_id.

Each version has an imageUrl when Google saved it as a picture, and a previewUrl otherwise. For text and video ads we also read one live preview to get the headline, description, landing page and YouTube video. Text that only exists inside an image stays null, since we don't read text from images.

Google publishes overall impressions, spend and targeting for political ads only. Per-country impressions are also published for ads shown in the EU.

Returns 404 not_found if the ad doesn't exist.

Example request

Copy one and replace YOUR_API_KEY with your API key (get one free). The code versions read the key from the LURKAPI_API_KEY environment variable instead.

Language

Parameters

Add them to the URL after a ?. Join several with &.

ParameterDescription
url
stringoptional
The ad's Transparency Center link, e.g. https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR11071274990039990273. Required unless you pass both ids.
Example
https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR11071274990039990273?region=US
advertiser_id
stringoptional
The advertiser's id (AR…), with creative_id, instead of url.
creative_id
stringoptional
The ad's id (CR…), with advertiser_id, instead of url.

Example response

A real response, captured from the live API. Lists are trimmed to a couple of items, and long text such as media links is cut short with ….

Show the example response (2 KB)
{
  "success": true,
  "credits_remaining": 999958,
  "credits_charged": 1,
  "advertiserId": "AR16735076323512287233",
  "creativeId": "CR11071274990039990273",
  "advertiserName": "Nike, Inc.",
  "format": "video",
  "adUrl": "https://adstransparency.google.com/advertiser/AR16735076323512287233/cre…",
  "firstShown": null,
  "lastShown": "2026-10-02T09:57:07.000Z",
  "daysShown": null,
  "overallImpressions": null,
  "spend": null,
  "targeting": null,
  "targetingCategories": null,
  "creativeRegions": [
    {
      "regionCode": "US",
      "regionName": "United States"
    }
  ],
  "regionStats": [
    {
      "regionCode": "US",
      "regionName": "United States",
      "firstShown": null,
      "lastShown": "2026-10-02",
      "impressions": null,
      "platformImpressions": []
    }
  ],
  "eeaStats": null,
  "usStats": null,
  "variations": [
    {
      "destinationUrl": "https://www.nike.com/retail/",
      "headline": "Engineered for Max Airflow",
      "description": "Maximum breathability meets ultra-light comfort in new Nike Aero-FIT styles.",
      "allText": null,
      "imageUrl": null,
      "previewUrl": "https://displayads-formats.googleusercontent.com/ads/preview/content.js?…",
      "videoId": "RZ1MLoOdWcc"
    },
    {
      "destinationUrl": null,
      "headline": null,
      "description": null,
      "allText": null,
      "imageUrl": null,
      "previewUrl": "https://displayads-formats.googleusercontent.com/ads/preview/content.js?…",
      "videoId": null
    }
  ]
}

Response fields

Every field in a successful response, and what it means. A name with [] belongs to each item of a list: targeting.location.included[].criterionId is the criterionId of every item in targeting.location.included. null means there's no value.

Show all 95 fields
FieldTypeDescription
successtrueAlways true here; errors have success: false.
credits_remainingnumberYour balance after this call. On anonymous playground calls: free tries left today.
credits_chargednumberCredits this call cost; 0 on free endpoints. On anonymous playground calls: tries used (1).
advertiserIdstringThe advertiser's id (AR…). Pass it as advertiser_id to company ads.
creativeIdstringThe ad's id (CR…).
advertiserNamestringcan be nullWho paid for the ad (Google's "paid for by" name), e.g. Nike, Inc.; it can differ from the advertiser account, e.g. for agencies. null when Google shows none, which is common (political ads, many EU ads).
formatstringcan be nulltext, image or video. Google often saves text ads as a picture of the ad.
adUrlstringThe ad's page on the Ads Transparency Center.
firstShownstringcan be nullWhen the ad was first shown, ISO 8601 (UTC). Google often leaves it out here; company ads always has it.
lastShownstringcan be nullWhen the ad was last shown, ISO 8601 (UTC). Today's date for ads still running.
daysShownnumbercan be nullHow many days the ad has been shown. A long run usually means the ad works. null when Google leaves it out.
overallImpressionsobjectcan be nullImpressions as the range Google reports. Political ads only; null otherwise.
overallImpressions.minnumberLower bound of impressions.
overallImpressions.maxnumberUpper bound of impressions.
spendobjectcan be nullSpend as the range Google reports. Political ads only; null otherwise.
spend.currencystringCurrency code, e.g. USD.
spend.lowernumberLower bound of the spend, in currency.
spend.uppernumberUpper bound of the spend, in currency.
targetingobjectcan be nullWho the ad targeted. Political ads only; null otherwise. Empty lists can still mean targeting was used: Google doesn't always list the groups.
targeting.ageobjectAge groups (0-17, 18-24, 25-34, 35-44, 45-54, 55-64, 65+, unknown) targeting.
targeting.age.includedstring[]Age groups (0-17, 18-24, 25-34, 35-44, 45-54, 55-64, 65+, unknown) the ad targeted.
targeting.age.excludedstring[]Age groups (0-17, 18-24, 25-34, 35-44, 45-54, 55-64, 65+, unknown) the ad excluded.
targeting.genderobjectGenders (male, female, unknown) targeting.
targeting.gender.includedstring[]Genders (male, female, unknown) the ad targeted.
targeting.gender.excludedstring[]Genders (male, female, unknown) the ad excluded.
targeting.locationobjectLocation targeting.
targeting.location.includedobject[]Locations the ad targeted.
targeting.location.included[].criterionIdstringGoogle's location id, e.g. 2840 (United States) or 1015229 (a city).
targeting.location.included[].namestringcan be nullThe country's name for country-level ids; null for cities and regions, which we don't resolve.
targeting.location.included[].fullNamestringcan be nullSame as name for countries; null for cities and regions.
targeting.location.included[].countryCodesstring[]The country code for country-level ids, e.g. ["US"]; empty otherwise.
targeting.location.excludedobject[]Locations the ad excluded.
targeting.location.excluded[].criterionIdstringGoogle's location id, e.g. 2840 (United States) or 1015229 (a city).
targeting.location.excluded[].namestringcan be nullThe country's name for country-level ids; null for cities and regions, which we don't resolve.
targeting.location.excluded[].fullNamestringcan be nullSame as name for countries; null for cities and regions.
targeting.location.excluded[].countryCodesstring[]The country code for country-level ids, e.g. ["US"]; empty otherwise.
targetingCategoriesobjectcan be nullWhich kinds of targeting the ad used, as Google lists them for ads shown in the EU and some political ads; null when Google doesn't say.
targetingCategories.demographicsobjectTargeting by demographic info (age, gender, language, parental status, household income).
targetingCategories.demographics.includedbooleanWhether the ad targeted people by demographic info (age, gender, language, parental status, household income).
targetingCategories.demographics.excludedbooleanWhether the ad excluded people by demographic info (age, gender, language, parental status, household income).
targetingCategories.locationsobjectTargeting by geographic location.
targetingCategories.locations.includedbooleanWhether the ad targeted people by geographic location.
targetingCategories.locations.excludedbooleanWhether the ad excluded people by geographic location.
targetingCategories.contextualSignalsobjectTargeting by contextual signals (the pages they visit, the keywords they search).
targetingCategories.contextualSignals.includedbooleanWhether the ad targeted people by contextual signals (the pages they visit, the keywords they search).
targetingCategories.contextualSignals.excludedbooleanWhether the ad excluded people by contextual signals (the pages they visit, the keywords they search).
targetingCategories.topicsOfInterestobjectTargeting by topics of interest.
targetingCategories.topicsOfInterest.includedbooleanWhether the ad targeted people by topics of interest.
targetingCategories.topicsOfInterest.excludedbooleanWhether the ad excluded people by topics of interest.
targetingCategories.customerListsobjectTargeting by the advertiser's customer lists (data such as names and emails).
targetingCategories.customerLists.includedbooleanWhether the ad targeted people by the advertiser's customer lists (data such as names and emails).
targetingCategories.customerLists.excludedbooleanWhether the ad excluded people by the advertiser's customer lists (data such as names and emails).
creativeRegionsobject[]Countries where the ad was shown.
creativeRegions[].regionCodestring2-letter country code, e.g. US.
creativeRegions[].regionNamestringCountry name in English.
regionStatsobject[]Per-country delivery: dates and, for political ads and ads shown in the EU, impressions.
regionStats[].regionCodestring2-letter country code, e.g. US.
regionStats[].regionNamestringCountry name in English.
regionStats[].firstShownstringcan be nullFirst day shown in this country, YYYY-MM-DD; often null unless the ad is political or shown in the EU.
regionStats[].lastShownstringcan be nullLast day shown in this country, YYYY-MM-DD.
regionStats[].impressionsobjectcan be nullImpressions in this country, for political ads and ads shown in the EU; null otherwise.
regionStats[].impressions.minnumberLower bound of impressions.
regionStats[].impressions.maxnumberUpper bound of impressions.
regionStats[].platformImpressionsobject[]Impressions per Google product in this country, as Google reports them for ads shown in the EU; empty otherwise.
regionStats[].platformImpressions[].platformstringcan be nullThe Google product.
regionStats[].platformImpressions[].minnumbercan be nullLower bound of impressions there.
regionStats[].platformImpressions[].maxnumbercan be nullUpper bound of impressions there.
eeaStatsobjectcan be nullTotals across the European Economic Area (the EU plus Iceland, Liechtenstein and Norway), which Google publishes for ads shown there; null otherwise.
eeaStats.firstShownstringcan be nullFirst day shown across the EEA, YYYY-MM-DD; often null unless the ad is political or shown in the EU.
eeaStats.lastShownstringcan be nullLast day shown across the EEA, YYYY-MM-DD.
eeaStats.impressionsobjectcan be nullImpressions across the EEA, for political ads and ads shown in the EU; null otherwise.
eeaStats.impressions.minnumberLower bound of impressions.
eeaStats.impressions.maxnumberUpper bound of impressions.
eeaStats.platformImpressionsobject[]Impressions per Google product across the EEA, as Google reports them for ads shown in the EU; empty otherwise.
eeaStats.platformImpressions[].platformstringcan be nullThe Google product.
eeaStats.platformImpressions[].minnumbercan be nullLower bound of impressions there.
eeaStats.platformImpressions[].maxnumbercan be nullUpper bound of impressions there.
usStatsobjectcan be nullTotals across the United States, which Google publishes for political ads; null otherwise.
usStats.firstShownstringcan be nullFirst day shown across the US, YYYY-MM-DD; often null unless the ad is political or shown in the EU.
usStats.lastShownstringcan be nullLast day shown across the US, YYYY-MM-DD.
usStats.impressionsobjectcan be nullImpressions across the US, for political ads and ads shown in the EU; null otherwise.
usStats.impressions.minnumberLower bound of impressions.
usStats.impressions.maxnumberUpper bound of impressions.
usStats.platformImpressionsobject[]Impressions per Google product across the US, as Google reports them for ads shown in the EU; empty otherwise.
usStats.platformImpressions[].platformstringcan be nullThe Google product.
usStats.platformImpressions[].minnumbercan be nullLower bound of impressions there.
usStats.platformImpressions[].maxnumbercan be nullUpper bound of impressions there.
variationsobject[]Every version of the ad Google shows. For text and video ads, we read the live preview of the first version that has one.
variations[].destinationUrlstringcan be nullLanding page, from the version's live preview. For search ads it can be just the display URL (e.g. nike.com); null when we didn't read one.
variations[].headlinestringcan be nullHeadline, from the live preview; null for image-only versions and ones we didn't read.
variations[].descriptionstringcan be nullDescription text, from the live preview; null for image-only versions and ones we didn't read.
variations[].allTextstringcan be nullAll text on the ad. Always null for now, since we don't read text from images.
variations[].imageUrlstringcan be nullPicture of this version; null when it only has a live preview.
variations[].previewUrlstringcan be nullGoogle's live preview of this version (a script); null when there's an imageUrl.
variations[].videoIdstringcan be nullThe YouTube video id of a video ad, from the live preview (youtube.com/watch?v=<id>); null otherwise.

Cost and freshness

Each call costs 1 credit. Calls turned away before they reach the platform (invalid parameters, a key or balance problem, a rate limit) are free, and so are 5xx errors. A not_found is charged, since the platform was checked. How charging works.

Answers are cached for up to 12 hours. A repeat call within that time can return the same data, and costs the same.

Errors

A failed call returns success: false, an error message, a code your program can check, and a docs link. These are the errors this endpoint can return. All error codes.

StatusCodeMeaning
401missing_api_keyNo API key was sent. Put it in the x-api-key header.
401invalid_api_keyThis key doesn't exist or was revoked.
402insufficient_creditsNot enough credits for this call. Buy a pack, or wait for tomorrow's free top-up.
402over_max_creditsThis call would cost more than the max_credits you set. The error says what it needs; raise max_credits to allow it. Not charged.
403account_suspendedThis account is suspended. Email support@lurkapi.com. Not charged.
404not_foundWhat you asked for (a post, an ad, a subreddit) doesn't exist, or there's no endpoint at that path. Charged if the platform was checked.
405method_not_allowedEndpoints only take GET, with parameters in the URL.
429rate_limitedToo many calls in a short time. Wait as many seconds as the retry-after header says, then retry.
500internal_errorSomething broke on our side. Retry. Not charged.
502upstream_errorThe platform didn't send a usable answer. Retry. Not charged.
503upstream_busyAll our connections to the platform are busy. Retry in a few seconds. Not charged.
504upstream_timeoutThe platform took over 30 seconds to answer (90 for web pages). Retry. Not charged.

Use it in Claude

Connect LurkAPI to Claude and ask in plain English. This endpoint is the google_ad tool. For example:

Ask Claude
Use LurkAPI's google_ad tool with url "https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR11071274990039990273?region=US", then summarize what you find.

Claude calls google_ad with arguments like these, and each call costs 1 credit:

Tool arguments
{"url": "https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR11071274990039990273?region=US"}

To save tokens, tool results leave out empty fields, keep one URL per image or video, and give transcripts as plain text unless you pass timestamps=true. A result over 45,000 characters comes in parts. Its _note gives the offset for the next part, and later parts are free for 15 minutes. Pass trim=false for the full response.

From the blog

All posts