AnswerLine Start free

, Google · Brand Monitoring

Monitor Google AI Overviews for your keywords

An AI Overview above the organic results changes what an organic ranking is worth, depending on whether it appears and whether it cites you. To monitor it, request the overview with the Google results for a fixed keyword list, per market, and track three numbers over time: how often an overview appears, how often it cites you, and where it skips pages that already rank.

Definitions

An AI Overview is the AI-generated summary Google shows at the top of some results pages, with links to supporting sources. Google says it shows one when “our systems determine that generative AI can be especially helpful” (AI Overviews in Google Search help, checked 2026-09-17).

Step 1: request the overview with the results

{
  "query": "project management software",
  "country": "US",
  "include": { "aioverview": { "markdown": true } }
}

Send it to POST /v1/monitor/google, or as the payload of a task with "taskType": "GOOGLE" for keyword lists.

The request fields that matter for AI Overview tracking:

Field Notes
query The search query. Required.
country or gl Result geography (ISO 3166-1 alpha-2). GET /v1/countries?model=aioverview lists the countries where the overview can be requested.
location or uule City-level targeting: a Google canonical City,Region,Country name, or a pre-encoded UULE. Mutually exclusive.
pages 1 to 10 result pages; each page after the first is charged.
include.aioverview An object; its presence requests the overview. {"markdown": true} also returns it as Markdown.
include.paaAioverview Fills AI-Overview-type People Also Ask items with their Markdown and sources.

curl

curl -X POST https://api.answerline.dev/v1/monitor/google \
  -H "Authorization: Bearer $ANSWERLINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "project management software",
    "country": "US",
    "include": { "aioverview": { "markdown": true } }
  }'

Python (requests)

import os
import requests

API = "https://api.answerline.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['ANSWERLINE_API_KEY']}"}

resp = requests.post(
    f"{API}/v1/monitor/google",
    headers=HEADERS,
    json={
        "query": "project management software",
        "country": "US",
        "include": {"aioverview": {"markdown": True}},
    },
    timeout=360,
)
resp.raise_for_status()
result = resp.json()["result"]
overview = result.get("aioverview")
print("overview shown:", overview is not None)

TypeScript (@answerline/sdk)

import { Client } from "@answerline/sdk";

interface AiOverview {
  text?: string;
  markdown?: string;
  sources?: { position: number; url: string; label?: string; description?: string; redirectLink?: string }[];
  citationPills?: { citationPillId: number; position: number; url: string; domain: string; label: string }[];
  relatedLinks?: { citationPillId: number; url: string; domain: string; label: string }[];
}
interface GoogleResult {
  organicResults?: { position: number; title: string; link: string; page: number }[];
  aioverview?: AiOverview | null;
}

const client = new Client({ apiKey: process.env.ANSWERLINE_API_KEY! });
const { result } = await client.monitor.google<GoogleResult>({
  query: "project management software",
  country: "US",
  include: { aioverview: { markdown: true } },
});
console.log(result.aioverview ? result.aioverview.sources?.map((s) => s.url) : "no overview");

The TypeScript SDK is on npm as @answerline/sdk; the Python examples use requests.

Step 2: read the response

result.aioverview is null when the results page had no AI Overview. Otherwise it holds:

Field Meaning
text The overview as plain text.
markdown The overview as Markdown, when include.aioverview.markdown is true.
sources[] The source rail: position (1-based), url, label, description, and redirectLink when Google served the link as a redirect.
citationPills[] The inline citation chips, one entry per chip-and-source pair: citationPillId, position (into aioverview.sources), url, domain, label, optional description and redirectLink. Omitted when there are no chips.
relatedLinks[] Links in a chip’s “related links” flyout that are not in the source rail. They share the chip’s citationPillId and have no position.
videos[] Videos in the overview: url, title, thumbnail, source, platform, date, duration.
ads[] Sponsored ads inside the overview: position, title, url, type, plus domain and description for text ads or price, old_price and store for shopping ads.

A chip citing several sources appears once per source with a shared citationPillId; group by it to rebuild the chip. Because related links also appear inside markdown, the Markdown can contain more URLs than sources and citationPills; relatedLinks accounts for the extras.

Next to it, result.organicResults lists organic results with position, title, link, displayedLink, snippet, date, page and sitelinks. With include.paaAioverview, result.peopleAlsoAsk items of type AIOVERVIEW also carry markdown and sources: smaller overviews for the follow-up questions, useful for People Also Ask research.

Wherever a redirectLink appears, the sibling url or link already holds the resolved destination. To resolve one yourself, POST /v1/monitor/google/goto with {"url": "<redirectLink>"}; it is free.

Step 3: 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)
    in_chip = any(on_domain(p["url"], domain) for p in (overview or {}).get("citationPills", []))
    return {"has_overview": overview is not None, "cited_position": cited, "in_chip": in_chip, "organic_position": organic}

To see who is cited instead, group aioverview.sources by host across keywords:

from collections import Counter

def cited_hosts(results: list[dict]) -> list[tuple[str, int]]:
    counts = Counter()
    for result in results:
        for source in (result.get("aioverview") or {}).get("sources", []):
            counts[urlsplit(source["url"]).hostname or ""] += 1
    return counts.most_common(20)

The hosts at the top of that list are the competitors for the overview, which are not always the ones at the top of the organic results. Competitor analysis covers reporting on this.

Worked example

Illustrative keyword data, computed with the functions above for one market:

Keyword has_overview cited_position organic_position Reading
A true 2 4 Cited and ranking
B true null 3 Rank gap: fix first
C false null 1 No overview to win
D true null null Neither: content gap

For these four keywords, presence rate is 3/4 = 75%, citation share is 1/3 (A among A, B, D), and the rank gap list is B.

Step 4: run it on a schedule

Submit the keyword list as batches of GOOGLE tasks with an idempotency key per keyword, market and day, and collect results by webhook:

tasks = [
    {
        "taskType": "GOOGLE",
        "payload": {"query": kw, "country": country, "include": {"aioverview": {"markdown": True}}},
        "idempotencyKey": f"aio-{kw}-{country}-2026-09-15",
        "webhook": {"url": "https://example.com/hooks/aioverview"},
    }
    for kw in keywords
    for country in ("US", "GB")
]
for start in range(0, len(tasks), 500):
    requests.post(f"{API}/v1/async/task/batch", headers=HEADERS, json=tasks[start:start + 500], timeout=360)

A batch holds 1 to 500 tasks. The webhook receives the GET /v1/async/task/{id} JSON, with the Google result under response.result. Tracking AI Overviews with async batches and webhooks covers the SDK version and webhook handler in detail, and the rank-tracking pipeline post covers the plumbing. A single run is a snapshot, so compare trends across runs.

What it costs

Per billing, at the Starter tier:

Request Price
1 page, no overview $0.00103
1 page with include.aioverview $0.00174
1 page with include.aioverview and include.paaAioverview $0.00174
3 pages with include.aioverview $0.00316

The overview add-on is $0.00071, charged once when Google shows an overview; paaAioverview is free; each extra page adds $0.00071. Worked example: 200 keywords x 2 markets as 1-page tasks with the overview is 400 tasks x $0.00174 = $0.696 per run. See pricing for the tiers and cost planning for cadence trade-offs.

Decision criteria

Pitfalls

For Google’s conversational surface, see AI Mode; for the endpoint’s full field list, the Google Search engine page.

Related: getting AI Overviews as JSON and tracking AI Overviews with async batches and webhooks.

Questions

How much does a Google request with the AI Overview cost?

One results page with include.aioverview costs $0.00174 on every tier. Each page after the first adds $0.00071, so a 3-page task with the AI Overview costs $0.00316.

What is the rank gap on a keyword?

Keywords where your domain ranks organically but the overview does not cite it. Compare organicResults positions with the domains the overview cites for the same keyword and market; that split shows where an existing ranking stops earning visibility.

Does include.paaAioverview cost extra on top of include.aioverview?

No. include.paaAioverview is free; include.aioverview adds $0.00071 once when Google shows an overview. Each hydrated People Also Ask item makes the response take longer.

Can I track AI Overviews for a specific city?

Yes. Send location, a Google canonical name such as Austin,Texas,United States, or a uule with the Google Search request, and treat the location as a dimension in every metric.

How do I resolve redirectLink values in the AI Overview?

The sibling url already holds the resolved destination. When you need to resolve a redirectLink yourself, POST it to /v1/monitor/google/goto, which is free.

Try it on your own prompts

100 free requests on any engine, no card. One POST returns the answer, sources and citations as JSON.

Keep reading