Monitoring Google AI Overviews for your keywords
At the time of writing the Google Search endpoint is listed as coming soon. The request and fields below are its documented contract; the Google Search page shows its availability.
When Google answers a query above the organic results, whether that AI Overview appears, and whether it cites you, changes what an organic ranking is worth. Here is how to measure it per keyword and market.
Request the overview with the results
{
"query": "project management software",
"country": "US",
"location": "Austin,Texas,United States",
"device": "desktop",
"include": { "aioverview": { "markdown": true } }
}
Send it to POST /v1/monitor/google, or as the payload of a task with "taskType": "GOOGLE" for keyword lists.
include.aioverviewis an add-on charged once per request (pricing).include.paaAioverview: truealso fills AI-Overview-style People Also Ask items with their content and sources at no extra credit cost, but responses take longer.location(a Google canonical location name) oruulenarrows results to a place; send one, not both.deviceselects the desktop or a mobile results page.pagesfetches up to 10 result pages; each page after the first is charged.
Read the response
result.aioverview is null when no AI Overview was available. Otherwise it holds:
text, and withmarkdown: truealsomarkdown: the answer.sources: the source rail, each withposition,url,labelanddescription.citationPills: the inline citation chips. A chip citing several sources appears once per source with a sharedcitationPillId; group by it to rebuild the chip.
Next to it, result.organicResults lists organic results with position, title, link and page.
Three numbers per keyword
from urllib.parse import urlsplit
def on_domain(url: str, domain: str) -> bool:
host = urlsplit(url).hostname or ""
return host == domain or host.endswith("." + domain)
def aio_metrics(result: dict, domain: str) -> dict:
overview = result.get("aioverview")
organic = next((r["position"] for r in result.get("organicResults", []) if on_domain(r["link"], domain)), None)
cited = next((s["position"] for s in (overview or {}).get("sources", []) if on_domain(s["url"], domain)), None)
return {"has_overview": overview is not None, "cited_position": cited, "organic_position": organic}
- Presence rate: the share of keywords with
has_overview. Track it per market and device, since each is a separate results page. - Citation share: among keywords with an overview, the share with a
cited_position. - Rank gap: keywords where you rank organically but the overview doesn’t cite you. Start there: those pages already rank for the query.
To see who is cited instead, group aioverview.sources by host across keywords.
Running it on a schedule
Submit the keyword list as batches of tasks with an idempotency key per keyword, market, device and day, and collect results by webhook; the rank-tracking pipeline post covers the plumbing. A single run is a snapshot, so compare trends across runs.