Skip to content

Google API

The TrueScrape Google API exposes 8 public endpoints covering Ad details and Ads run by an advertiser or domain. Every call is a GET against public, logged-out pages and returns the same unified schema as every other platform here. Calls cost 1–5 credits each. A cache hit is free, and a failed or empty response is never charged.

Endpoints

EndpointReturnsCreditsCacheableBatchable
/v1/google/ad-library/adAd details1yesyes
/v1/google/ad-library/advertiser-adsAds run by an advertiser or domain2yesyes
/v1/google/ad-library/advertisersFind advertisers in the Ads Transparency Centre1yesyes
/v1/google/jobsGoogle Jobs results5yesyes
/v1/google/maps-searchGoogle Maps place search5yesyes
/v1/google/newsGoogle News results5yesyes
/v1/google/searchWeb search results1yesyes
/v1/google/shoppingGoogle Shopping results5yesyes

Reference

GET/v1/google/ad-library/advertiser-ads2 creditscacheablebatchable

Ads run by an advertiser or domain

Creatives in the Ads Transparency Centre for one advertiser id or one verified domain, with first-shown and last-shown dates. Pass the cursor from the previous response to page. **Required:** Pass either domain or advertiser_id.

ParameterTypeRequiredDescription
domainstringnoVerified advertiser domain, e.g. "nike.com"
advertiser_idstringnoAdvertiser id from /ad-library/advertisers, e.g. "AR167..."
regionstringnoTwo-letter country code (US, GB, DE, IN, ...) or a Google geo criteria iddefaults to US
cursorstringnoContinuation token from the previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns an object with items, totalLower, totalUpper.

Fields
FieldTypePresentDescription
itemsAd[]always
totalLowernumber | nullalwaysLower bound of the archive estimate of how many ads match, across every page.
totalUppernumber | nullalwaysUpper bound of that estimate.
curl
curl "$API/v1/google/ad-library/advertiser-ads?cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/google/ad-library/advertiser-ads?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 2 credits, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/google/ad-library/advertiser-ads",
    params={
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/google/ad-library/advertiser-ads
Open the full playground
GET/v1/google/ad-library/advertisers1 creditcacheablebatchable

Find advertisers in the Ads Transparency Centre

Advertisers matching a name, with the advertiser id that /v1/google/ad-library/advertiser-ads needs, plus the verified domains Google suggests for the same term in domains. Without region every region is searched. postCount and adCountUpper are the lower and upper bounds of the ad-count range the archive publishes, counted within region when one is given.

ParameterTypeRequiredDescription
querystringyesAdvertiser or brand name, e.g. "nike"
regionstringnoTwo-letter country code (US, GB, DE, IN, ...) or a Google geo criteria id. Omit to search every region.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns an object with items, domains.

Fields
FieldTypePresentDescription
itemsobject[]always
items[].platformone of 32 stringsalways
items[].idstringalwaysThe platform's own id for the account, such as a channel id or a numeric user id, always as a string.
items[].handlestring | nullalwaysThe account handle without the leading @. Null when the platform has no handles.
items[].displayNamestring | nullalways
items[].biostring | nullalways
items[].avatarUrlstring | nullalways
items[].bannerUrlstring | nullalways
items[].urlstring | nullalways
items[].verifiedboolean | nullalwaysWhether the platform shows a verification badge on the account. Null where the platform has no public badge or does not expose it.
items[].followerCountnumber | nullalwaysFollowers, subscribers, or the platform's nearest equivalent. Null when the account hides the count or the platform does not expose it.
items[].followingCountnumber | nullalways
items[].postCountnumber | nullalwaysPosts, videos, tracks, repositories, or the platform's nearest equivalent that the account has published.
items[].viewCountnumber | nullalwaysLifetime views across the account, where the platform exposes a total.
items[].likeCountnumber | nullmay be absentTotal likes received across all of the creator's posts. Distinct from `viewCount`. Absent when the platform does not expose it.
items[].isPrivateboolean | nullalways
items[].isBusinessboolean | nullalwaysWhether the platform classifies the account as a business or organisation rather than a person or creator. Null where the platform draws no such line or does not expose it. On Facebook every Page counts, including Pages for public figures.
items[].categorystring | nullalwaysA label the platform attaches to the account, such as a business category, a genre or an account type. What it holds varies by platform.
items[].locationstring | nullalwaysLocation as the platform shows it: a city, a country, a region code or an address, depending on the platform.
items[].externalLinksstring[]alwaysLinks the account lists on its profile, such as a website or other social accounts.
items[].createdAtstring | nullalwaysWhen the account was created. Usually an ISO 8601 timestamp; some platforms expose only the date as shown on the profile.
items[].fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
items[].adCountUppernumber | nullalwaysUpper bound of the ad-count range the archive publishes; `postCount` is the lower bound.
domainsstring[]always
curl
curl "$API/v1/google/ad-library/advertisers?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/google/ad-library/advertisers?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/google/ad-library/advertisers",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/google/ad-library/advertisers
Open the full playground
GET/v1/google/jobs5 creditscacheablebatchable

Google Jobs results

Job postings for a query: title, company, location and the board it was syndicated from. Shares the /search anti-bot gate google.search already documents; a blocked attempt returns upstream_blocked and is not charged.

ParameterTypeRequiredDescription
querystringyesSearch query
tldstringnoGoogle marketplace TLD. One of: com, co.uk, ca, de, es, fr, it, co.jp, in, cn, com.sg, com.mx, ae, com.br, nl, com.au, com.tr, sa, se, pl. Defaults to "com".defaults to com
country_codestringnoTwo-letter country code. Sets gl when gl is not given.
hlstringnoHost language for the results page, e.g. "en", "de". Defaults to "en".defaults to en
glstringnoTwo-letter country code Google should bias results toward.
uulestringnoEncoded Google location string for precise geo-targeting.
startnumberno0-based result offset.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of JobPosting in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstring | nullalwaysIdentifier for the posting. Where the source shows none, this is the posting URL.
titlestring | nullalways
companystring | nullalways
locationstring | nullalways
viastring | nullalwaysThe job board the posting was listed through, as in "via LinkedIn".
descriptionstring | nullalwaysSnippet of the job description shown with the result.
urlstring | nullalways
tagsstring[]always
postedAtstring | nullalways
fetchedAtstringalwaysWhen this record was retrieved, as an ISO 8601 timestamp.
curl
curl "$API/v1/google/jobs?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/google/jobs?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 5 credits, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/google/jobs",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
GET/v1/google/maps-search5 creditscacheablebatchable

Google Maps place search

Business listings near a coordinate: name, address, phone, rating and hours. Google Maps requires JavaScript to render its result list; an unrendered response returns upstream_blocked and is not charged, rather than a silent empty success.

ParameterTypeRequiredDescription
querystringyesSearch query
tldstringnoGoogle marketplace TLD. One of: com, co.uk, ca, de, es, fr, it, co.jp, in, cn, com.sg, com.mx, ae, com.br, nl, com.au, com.tr, sa, se, pl. Defaults to "com".defaults to com
country_codestringnoTwo-letter country code. Sets gl when gl is not given.
hlstringnoHost language for the results page, e.g. "en", "de". Defaults to "en".defaults to en
glstringnoTwo-letter country code Google should bias results toward.
uulestringnoEncoded Google location string for precise geo-targeting.
startnumberno0-based result offset.
latitudenumberyesLatitude of the search centre
longitudenumberyesLongitude of the search centre

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Place in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstring | nullalways
namestring | nullalways
addressAddressalways
latitudenumber | nullalways
longitudenumber | nullalways
phonestring | nullalways
websitestring | nullalwaysThe business's own website.
urlstring | nullalwaysLink to the place's listing on the map service.
ratingnumber | nullalwaysAverage star rating, out of 5.
reviewCountnumber | nullalways
priceLevelstring | nullalwaysPrice band as the listing shows it, such as `$` or `$$`. The scale varies by locale.
categoriesstring[]always
hoursRecord<string, string[]>alwaysOpening hours keyed by lowercase weekday, such as `monday`. Each value is the hours text as the listing published it.
imageUrlsstring[]always
fetchedAtstringalwaysWhen this record was retrieved, as an ISO 8601 timestamp.
curl
curl "$API/v1/google/maps-search?query=ai%20agents&latitude=%3Clatitude%3E&longitude=%3Clongitude%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  latitude: '<latitude>',
  longitude: '<longitude>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/google/maps-search?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 5 credits, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/google/maps-search",
    params={
        "query": "ai agents",
        "latitude": "<latitude>",
        "longitude": "<longitude>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/google/maps-search
Open the full playground
GET/v1/google/news5 creditscacheablebatchable

Google News results

News articles for a query: title, source, and published time. Shares the /search anti-bot gate google.search already documents; a blocked attempt returns upstream_blocked and is not charged.

ParameterTypeRequiredDescription
querystringyesSearch query
tldstringnoGoogle marketplace TLD. One of: com, co.uk, ca, de, es, fr, it, co.jp, in, cn, com.sg, com.mx, ae, com.br, nl, com.au, com.tr, sa, se, pl. Defaults to "com".defaults to com
country_codestringnoTwo-letter country code. Sets gl when gl is not given.
hlstringnoHost language for the results page, e.g. "en", "de". Defaults to "en".defaults to en
glstringnoTwo-letter country code Google should bias results toward.
uulestringnoEncoded Google location string for precise geo-targeting.
startnumberno0-based result offset.
tbsh | d | w | m | ynoTime filter: hour/day/week/month/year, as Google's own qdr code.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of NewsArticle in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
positionnumber | nullalwaysRank of the article in the results, starting at 1.
titlestring | nullalways
sourcestring | nullalwaysName of the outlet that published the article.
descriptionstring | nullalwaysSnippet of the article shown with the result.
linkstring | nullalways
thumbnailUrlstring | nullalways
publishedAtstring | nullalwaysWhen the article was published, as the result displays it. Often relative, such as "2 hours ago", and not converted to a date.
fetchedAtstringalwaysWhen this record was retrieved, as an ISO 8601 timestamp.
curl
curl "$API/v1/google/news?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/google/news?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 5 credits, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/google/news",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
GET/v1/google/shopping5 creditscacheablebatchable

Google Shopping results

Shopping tiles for a query: title, price, currency and merchant. Shares the /search anti-bot gate google.search already documents; a blocked attempt returns upstream_blocked and is not charged.

ParameterTypeRequiredDescription
querystringyesSearch query
tldstringnoGoogle marketplace TLD. One of: com, co.uk, ca, de, es, fr, it, co.jp, in, cn, com.sg, com.mx, ae, com.br, nl, com.au, com.tr, sa, se, pl. Defaults to "com".defaults to com
country_codestringnoTwo-letter country code. Sets gl when gl is not given.
hlstringnoHost language for the results page, e.g. "en", "de". Defaults to "en".defaults to en
glstringnoTwo-letter country code Google should bias results toward.
uulestringnoEncoded Google location string for precise geo-targeting.
startnumberno0-based result offset.
tbsh | d | w | m | ynoTime filter: hour/day/week/month/year, as Google's own qdr code.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of SearchResultItem in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
positionnumber | nullalwaysRank of the result on the page it was read from, starting at 1, in the order the source served it.
idstring | nullalwaysThe listing id on its platform, such as an Amazon ASIN. Where the source shows no id, this is the result URL, or the title when there is no URL.
titlestring | nullalways
urlstring | nullalways
thumbnailUrlstring | nullalways
pricenumber | nullalwaysPrice shown on the result, in `currency`. Where a price range is shown, the lowest price.
currencystring | nullalwaysISO 4217 currency code for the amounts in this record, such as USD or EUR.
listPricenumber | nullalwaysThe struck-through reference price shown on the result, when there is one.
ratingnumber | nullalwaysAverage customer rating, out of 5.
reviewCountnumber | nullalways
sellerNamestring | nullalways
availabilityin_stock | out_of_stock | preorder | discontinued | unknown | nullalwaysStock status. `unknown` means the listing showed a status that could not be read as one of the other values.
badgesstring[]alwaysLabels shown on the result, such as Best Seller or Amazon's Choice.
isSponsoredboolean | nullalwaysTrue for a paid placement. False only where the source marks a result as not sponsored; a result with no sponsored label is null.
fetchedAtstringalwaysWhen this record was retrieved, as an ISO 8601 timestamp.
curl
curl "$API/v1/google/shopping?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/google/shopping?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 5 credits, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/google/shopping",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/google/shopping
Open the full playground

Questions

How much does the Google API cost?
Calls cost 1–5 credits each. Every endpoint is cacheable, and a cache hit costs nothing. A failed request and an empty result are both free, on every endpoint.
Does the Google API need a login or cookies?
No. Every endpoint reads public, logged-out pages only — no account, no cookies, no session. An API key identifies your own TrueScrape account and nothing else.
Can I fetch many Google targets in one request?
Yes. 8 of 8 are batchable: one POST to /v1/jobs/batch takes many targets and returns a job id to poll.
Can I watch Google endpoints for changes?
Yes, 4 of 8. A subscription polls on your schedule and fires your webhook only when the content changed; the rest carry x-subscribable: false in the spec.