Scraping is async: submit a run → poll → fetch records. See the flow in Quick Start; the shared envelope, run state machine, billing, and errors are in Auth & Error Handling.
Quick Facts
- Base URL:
https://api.antsdata.com/v1 - Auth: header
Authorization: Bearer ants_xxx(static API Key) - Content-Type:
application/json - Request body: every endpoint is
POST /v1/scraper/google/<resource>, with a uniform body{ "deliveryMode": "async", "recordLimit": 1000, "targets": [ … ] }; each element oftargets[]is one query (fields listed under each endpoint's "Target fields").
💡 You can also use
deliveryMode: "sync"(small jobs block until terminal, auto fallback to polling on timeout) — see quick-start · Sync mode.
- Submit receipt: on success returns HTTP 201 + a Run object (with
id,status: "queued"). Note theid. - Fetch: poll
GET /v1/scraper/runs/{id}byiduntilsucceeded, thenGET /v1/scraper/runs/{id}/records?page=&pageSize=to page records, orGET /v1/scraper/runs/{id}/download?format=json|csv|excelto download. Full end-to-end flow: Quick Start. - Billing: charged per successfully produced record; failed targets release the hold and are not billed. Details in Auth & Error Handling.
Endpoint Overview
| Group | Endpoint | Description |
|---|---|---|
| Maps | POST /v1/scraper/google/maps |
Place / business search, reverse geo, geocoding |
| Web Search | POST /v1/scraper/google/search |
Google web search (organic) results |
| Shopping | POST /v1/scraper/google/shopping |
Google Shopping products |
| News | POST /v1/scraper/google/news |
Google News results |
| Ads Transparency | POST /v1/scraper/google/ads-suggestions |
Advertiser / keyword suggestions (locate sponsor_id) |
| Ads Transparency | POST /v1/scraper/google/ads-creatives |
Ad creatives list |
| Ads Transparency | POST /v1/scraper/google/ads-creative-details |
Single creative details (with spend / impression ranges) |
| Ads Transparency | POST /v1/scraper/google/ads-advertiser |
Advertiser entity info |
Maps
POST /v1/scraper/google/maps
Extract Google Maps places / businesses: keyword search, reverse geo lookup, and geocoding.
Target fields (each element of targets[]):
| Field | Type | Required | Description |
|---|---|---|---|
query |
string | one of | Address / place name / business search term (or use lat+lng) |
lat |
number | — | Reverse-lookup latitude (paired with lng) |
lng |
number | — | Reverse-lookup longitude (paired with lat) |
mode |
string | — | geocode / reverse / places (auto-detected if empty) |
ll |
string | — | Business-search center point (e.g. @40.7128,-74.0060,15z) |
location |
string | — | Business-search natural-language area |
gl |
string | — | Country/region code (default us) |
hl |
string | — | UI language (default en) |
openNow |
boolean | — | Only businesses currently open (default false) |
minRating |
number | — | Minimum rating filter |
resultsLimit |
number | — | Business-search result cap (default 20) |
pageToken |
string | — | Pagination token |
Output fields (each record when fetching):
| Field | Type | Description |
|---|---|---|
places |
array | List of matched places |
places.placeId |
string | Google Place ID |
places.dataId |
string | Maps data_id |
places.title |
string | Business name |
places.address |
string | Address |
places.rating |
string | User rating |
places.reviewsCount |
number | Total review count |
places.priceLevel |
string | Price level |
places.categories |
array | Business categories |
places.lat |
string | Latitude |
places.lng |
string | Longitude |
places.phone |
string | Phone number |
places.website |
string | Website |
places.thumbnail |
string | Cover thumbnail URL |
nextPageToken |
string | Next-page token |
Submit example:
curl -X POST "https://api.antsdata.com/v1/scraper/google/maps" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deliveryMode": "async",
"recordLimit": 1000,
"targets": [
{ "query": "coffee shop", "location": "San Francisco, CA", "resultsLimit": 20 }
]
}'
→ 201 { "id": <run_id>, "status": "queued" }, then poll by id and fetch records (see Quick Start).
Web Search
POST /v1/scraper/google/search
Extract Google web search organic results.
Target fields (each element of targets[]):
| Field | Type | Required | Description |
|---|---|---|---|
query |
string | ✅ | Search keyword |
searchType |
string | — | web / image (default web) |
geo_location |
string | — | Geographic location (e.g. California,United States) |
host_language |
string | — | UI language hl (ignored if omitted) |
domain |
string | — | Google domain suffix google.<domain> (default com) |
page |
number | — | SERP page number (default 1) |
Output fields (each record when fetching):
| Field | Type | Description |
|---|---|---|
organic |
array | Organic web-search results (one record each) |
organic.pos |
number | Rank within the organic block |
organic.pos_overall |
number | Overall whole-page rank (incl. non-organic blocks) |
organic.title |
string | Title |
organic.favicon_text |
string | Site name / favicon text |
organic.url_shown |
string | Breadcrumb / displayed URL |
organic.url |
string | Landing URL |
organic.desc |
string | Snippet |
imageResults |
array | Image-search results (when searchType=image, one record each) |
imageResults.position |
number | Position index |
imageResults.thumbnailUrl |
string | Thumbnail URL |
imageResults.originalUrl |
string | Original full-size image URL |
imageResults.source |
string | Source domain |
imageResults.title |
string | Image title |
total_results_count |
string | Total-results text (e.g. About 1,230,000 results; null for some queries) |
ai_overview |
string | AI Overview summary as plain text (null when absent) |
Submit example:
curl -X POST "https://api.antsdata.com/v1/scraper/google/search" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deliveryMode": "async",
"recordLimit": 1000,
"targets": [
{ "query": "best web scraping tools", "geo_location": "California,United States", "host_language": "en" }
]
}'
→ 201 { "id": <run_id>, "status": "queued" }, then poll by id and fetch records (see Quick Start).
Shopping
POST /v1/scraper/google/shopping
Extract Google Shopping product listings.
Target fields (each element of targets[]):
| Field | Type | Required | Description |
|---|---|---|---|
query |
string | ✅ | Product search term |
gl |
string | — | Country/region (default us) |
hl |
string | — | UI language (default en) |
minPrice |
number | — | Minimum price (local currency) |
maxPrice |
number | — | Maximum price |
condition |
string | — | new / used / refurbished |
sortBy |
string | — | relevance / price_asc / price_desc / rating |
resultsLimit |
number | — | Result cap (default 30, max 200) |
Output fields (each record when fetching):
| Field | Type | Description |
|---|---|---|
totalResults |
number | Estimated total matches |
products |
array | Product list |
products.position |
number | Position index |
products.productId |
string | Google Shopping product ID |
products.title |
string | Product title |
products.link |
string | Shopping product detail page |
products.price |
object | Price information |
products.price.amount |
string | Current price |
products.price.currency |
string | Currency |
products.price.originalAmount |
string | Strikethrough original price |
products.seller |
string | Seller name |
products.rating |
string | Product rating |
products.reviewsCount |
number | Review count |
products.thumbnail |
string | Main-image thumbnail URL |
products.isSponsored |
boolean | Whether it is a sponsored / ad placement |
products.shipping |
string | Shipping description |
products.badges |
array | Platform badges |
products.offers |
array | Per-seller offer list |
products.offers.seller |
string | Seller name |
products.offers.price |
string | Price from this seller |
products.offers.currency |
string | Currency |
products.offers.condition |
string | Product condition |
products.offers.link |
string | Seller landing page |
Submit example:
curl -X POST "https://api.antsdata.com/v1/scraper/google/shopping" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deliveryMode": "async",
"recordLimit": 1000,
"targets": [
{ "query": "wireless earbuds", "gl": "us", "sortBy": "price_asc", "resultsLimit": 30 }
]
}'
→ 201 { "id": <run_id>, "status": "queued" }, then poll by id and fetch records (see Quick Start).
News
POST /v1/scraper/google/news
Extract Google News results across keyword, top, topic, and publication feeds.
Target fields (each element of targets[]):
| Field | Type | Required | Description |
|---|---|---|---|
feedType |
string | ✅ | keyword / top / topic / publication |
query |
string | conditional | Required when feedType=keyword (search term) |
topicId |
string | conditional | Required when feedType=topic |
publicationId |
string | conditional | Required when feedType=publication |
timeRange |
string | — | 1h / 1d / 7d / 1m / 1y (keyword only) |
cluster |
boolean | — | De-dup by event cluster (default true, keyword only) |
hl |
string | — | Language-region (default en-US) |
gl |
string | — | Country/region (default US) |
Output fields (each record when fetching):
| Field | Type | Description |
|---|---|---|
feedType |
string | Echo of the requested feed type |
articles |
array | News article list |
articles.title |
string | Article title |
articles.link |
string | Google News link |
articles.source |
string | Publishing source name |
articles.published |
string | Published time |
articles.snippet |
string | Content snippet |
articles.thumbnail |
string | Article thumbnail URL |
articles.clusterSize |
number | Number of related reports in the same event cluster (returned when clustering is on) |
Submit example:
curl -X POST "https://api.antsdata.com/v1/scraper/google/news" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deliveryMode": "async",
"recordLimit": 1000,
"targets": [
{ "feedType": "keyword", "query": "artificial intelligence", "timeRange": "7d", "gl": "US" }
]
}'
→ 201 { "id": <run_id>, "status": "queued" }, then poll by id and fetch records (see Quick Start).
Ads Transparency
Scrape Google's Ads Transparency Center: advertisers, ad creatives, and their impression / spend data. Typical chain: use Ads Suggestions to get a sponsor_id → Ads Creatives to list creative_ids → Ads Creative Details for spend / impression ranges; Ads Advertiser for entity info.
Ads Suggestions
POST /v1/scraper/google/ads-suggestions
Suggest advertisers / keywords by search term — use it to locate a sponsor_id.
Target fields (each element of targets[]):
| Field | Type | Required | Description |
|---|---|---|---|
keyword |
string | ✅ | Search term (e.g. nike / car insurance) |
Output fields (each record when fetching):
| Field | Type | Description |
|---|---|---|
kind |
string | Kind: advertiser / keyword / topic |
name |
string | Display name |
sponsor_id |
string | Advertiser ID (returned when kind=advertiser; usable as input to later endpoints) |
region |
string | Suggested region |
Submit example:
curl -X POST "https://api.antsdata.com/v1/scraper/google/ads-suggestions" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deliveryMode": "async",
"recordLimit": 1000,
"targets": [
{ "keyword": "nike" }
]
}'
→ 201 { "id": <run_id>, "status": "queued" }, then poll by id and fetch records (see Quick Start).
Ads Creatives
POST /v1/scraper/google/ads-creatives
List ad creatives by advertiser or keyword.
Target fields (each element of targets[]):
| Field | Type | Required | Description |
|---|---|---|---|
advertiser_id |
string | one of | Advertiser ID (or use query; comes from suggestions) |
query |
string | one of | Website domain / keyword (or use advertiser_id, e.g. nike.com) |
regions |
array | — | Region-code filter array (e.g. ["US","GB"]) |
start_date |
string | — | Run-start YYYY-MM-DD |
end_date |
string | — | Run-end YYYY-MM-DD |
platform |
number | — | Platform filter 1–6 (1=Search / 2=Display / 3=YouTube / 4=Maps / 5=Play / 6=Shopping) |
limit |
number | — | Creative cap (1–1000, default 100) |
topic |
string | — | Set political to switch to the political-ads schema |
Output fields (each record when fetching):
| Field | Type | Description |
|---|---|---|
creative_id |
string | Creative ID (usable as creative-details input) |
sponsor_id |
string | Advertiser ID |
format |
string | Creative format |
regions |
array | Served regions |
first_shown |
string | First shown |
last_shown |
string | Last shown |
Submit example:
curl -X POST "https://api.antsdata.com/v1/scraper/google/ads-creatives" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deliveryMode": "async",
"recordLimit": 1000,
"targets": [
{ "advertiser_id": "AR16735076323512287233", "regions": ["US"], "platform": 1, "limit": 100 }
]
}'
→ 201 { "id": <run_id>, "status": "queued" }, then poll by id and fetch records (see Quick Start).
Ads Creative Details
POST /v1/scraper/google/ads-creative-details
Full details for a single creative, including spend and impression ranges.
Target fields (each element of targets[]):
| Field | Type | Required | Description |
|---|---|---|---|
sponsor_id |
string | ✅ | Advertiser ID |
creative_id |
string | ✅ | Creative ID (fetch it from Ads Creatives first; do not hard-code) |
topic |
string | — | Set political to switch to the political schema |
Output fields (each record when fetching):
| Field | Type | Description |
|---|---|---|
creative_id |
string | Creative ID |
sponsor_id |
string | Advertiser ID |
first_shown |
string | First-shown time (ISO 8601) |
last_shown |
string | Last-shown time (ISO 8601) |
topic |
string | Ad topic (non-empty when political, else empty string) |
funder |
string | Funder / sponsor (disclosed for political ads, empty string otherwise) |
regions |
array | Per-region detail, each { code, first_shown, last_shown, min_times, max_times } (impression counts are ranges given as strings) |
impressions_lower |
number | Lower bound of impressions (disclosed for political / EU ads, null for regular ads) |
impressions_upper |
number | Upper bound of impressions (same as above) |
spend_lower |
number | Lower bound of spend (disclosed for political / EU ads, null for regular ads) |
spend_upper |
number | Upper bound of spend (same as above) |
eu_reach |
number | EU reach (disclosed for EU political ads, else null) |
Submit example:
curl -X POST "https://api.antsdata.com/v1/scraper/google/ads-creative-details" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deliveryMode": "async",
"recordLimit": 1000,
"targets": [
{ "sponsor_id": "AR16735076323512287233", "creative_id": "CR12886158981977866241" }
]
}'
→ 201 { "id": <run_id>, "status": "queued" }, then poll by id and fetch records (see Quick Start).
Ads Advertiser
POST /v1/scraper/google/ads-advertiser
Advertiser entity information.
Target fields (each element of targets[]):
| Field | Type | Required | Description |
|---|---|---|---|
advertiser_id |
string | ✅ | Advertiser ID (AR…) |
topic |
string | — | Set political to switch to the political-advertiser schema |
Output fields (each record when fetching):
| Field | Type | Description |
|---|---|---|
name |
string | Advertiser name |
legal_name |
string | Legal name |
disclosed_name |
string | Disclosed name |
regions |
array | Served countries / regions |
verified |
boolean | Whether verified |
Submit example:
curl -X POST "https://api.antsdata.com/v1/scraper/google/ads-advertiser" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deliveryMode": "async",
"recordLimit": 1000,
"targets": [
{ "advertiser_id": "AR16735076323512287233" }
]
}'
→ 201 { "id": <run_id>, "status": "queued" }, then poll by id and fetch records (see Quick Start).
Fetching Records & Billing
After submitting to any endpoint:
- Poll
GET /v1/scraper/runs/{id}untilstatus: "succeeded"(back off 1s→2s→5s). GET /v1/scraper/runs/{id}/records?page=1&pageSize=20to page records — eachitems[]element carries the "Output fields" listed per endpoint above; orGET /v1/scraper/runs/{id}/download?format=csvto download the full output.- Billing settles per successfully produced record (the run object's
chargedCredits); if all targets fail, the hold is released and nothing is billed.
End-to-end examples and the run state machine: Quick Start and Auth & Error Handling.
Next Steps
- Platform guides: TikTok · X · Instagram · Facebook · LinkedIn · YouTube · Amazon
- Synchronous search: Google SERP
- Auth & Error Handling — Unified envelope, run state machine, billing & error codes
FAQ
Q: Why don't I get data back directly after submitting?
Scraping is async: submit to get a run id, it runs in the background, you poll id until succeeded, then fetch records / download. See Quick Start.
Q: Can I query multiple targets at once?
Yes. targets is an array — one run can contain many queries (e.g. several search terms / advertisers). Per-target outcomes appear in the tasks[] of the polled run.
Q: Does Web Search always return an AI Overview?
No. The search endpoint returns organic results (pos / title / url / desc, etc.). AI Overview and other rich blocks only appear for topics where Google shows them and are not guaranteed. pos_overall reflects whole-page rank including non-organic blocks.
Q: Are Ads Transparency spend / impression figures exact?
No. Google only discloses ranges: spend_lower / spend_upper, impressions_lower / impressions_upper, and typically only for political / EU ads — for regular ads these fields are null. This API returns them as-is.
Q: Where does a creative's creative_id come from?
Call Ads Suggestions to get a sponsor_id, then Ads Creatives to list creative_ids, then query Ads Creative Details with both. Do not hard-code creative_id.
Q: Am I charged for failed scrapes?
No. If all targets fail the hold is released and nothing is billed; partial success is charged only for the records actually produced. See Auth & Error Handling.
Q: How is this page's Google different from "Google SERP"?
This page is the scraper product line (/v1/scraper/google/*): async runs, input is a targets[] array, and you poll for records after submitting. If you want search results returned synchronously (flat input, one call gets the data), use Google SERP (/v1/serp/google/*). The two share endpoint names (search / shopping / news / maps / ads-creatives / ads-creative-details), but their input shape and required fields differ — follow each page for its own contract.
