To check whether your website is cited in Google AI Overviews, send each important search query to the API and inspect data.sources. Parse every source URL, extract its hostname, and compare that hostname with your domain. Save the query, country, language, and check time with the result.

A match proves that your domain appeared in one captured AI Overview for one query and market. It does not prove that the site is always cited. A failed request also does not mean "not cited." Keep those outcomes separate.

The current endpoint is GET /ai-overview with query, gl, and hl. The Google AI Overviews API product page documents the current request path and plans.

Check one query and inspect its sources

What counts as a website citation?

For this checker, a citation is a returned source whose hostname equals your target domain. You can also choose to include subdomains. For example, docs.example.com belongs to example.com when subdomain matching is enabled.

Do not search for the domain as plain text inside a URL. The expression "example.com" in url also matches notexample.com and may match text inside a query string. A URL parser gives you the actual hostname.

A brand mention is different. Google may mention a brand in data.ai_overview without citing the brand's website. It may also cite a page without writing the brand name in the answer. Track mentions and linked citations as separate values.

Which queries should you check?

Start with searches connected with pages, products, or problems your site actually covers. A small list you understand is easier to review than an export containing thousands of unrelated keywords.

InputExampleWhy you need it
Target domainexample.comDefines the hostname you want to find
Queryhow does a heat pump workIdentifies the search you checked
CountryusKeeps results from different markets separate
LanguageenKeeps language variants separate
Check timeUTC timestampShows when the observation was collected

Use the same query list and inputs when you compare two dates. Otherwise, a change in the report may come from a different test setup rather than a different Google result.

Request the AI Overview and keep the sources

curl --request GET \
  --url "https://google-ai-overviews.p.rapidapi.com/ai-overview?query=how%20does%20a%20heat%20pump%20work&gl=us&hl=en" \
  --header "x-rapidapi-host: google-ai-overviews.p.rapidapi.com" \
  --header "x-rapidapi-key: $RAPIDAPI_KEY"

In the live test from August 5, 2026, each source object could contain url, title, site, and position. The answer was in data.ai_overview. These are test observations, so your code should still check types before using the fields.

FieldHow the checker uses it
data.ai_overviewDistinguishes an answer from a result with no overview
data.sourcesProvides the list searched for matching domains
source.urlProvides the cited page and a hostname fallback
source.siteProvides a domain value when present
source.positionRecords the observed order of the source

Check the HTTP status before reading this data. A timeout or server error belongs in the run log. Never convert it into a clean "not cited" result.

A complete Python domain checker

The script below calls the endpoint once per query. It removes a leading www., accepts subdomains, and rejects lookalike domains such as notexample.com.

import os
from urllib.parse import urlparse

import requests


API_URL = "https://google-ai-overviews.p.rapidapi.com/ai-overview"
TARGET_DOMAIN = "example.com"
QUERIES = [
    "how does a heat pump work",
    "heat pump maintenance checklist",
]


def normalize_host(value):
    if not isinstance(value, str) or not value.strip():
        raise ValueError("The hostname is empty.")

    candidate = value.strip().lower()
    if "://" not in candidate:
        candidate = f"https://{candidate}"

    host = urlparse(candidate).hostname
    if not host:
        raise ValueError(f"Cannot read a hostname from: {value}")

    host = host.rstrip(".")
    return host[4:] if host.startswith("www.") else host


def is_same_domain(source, target_domain, include_subdomains=True):
    if not isinstance(source, dict):
        return False

    source_value = source.get("site") or source.get("url")
    if not isinstance(source_value, str):
        return False

    try:
        source_host = normalize_host(source_value)
        target_host = normalize_host(target_domain)
    except ValueError:
        return False

    if source_host == target_host:
        return True

    return include_subdomains and source_host.endswith(f".{target_host}")


def check_query(query, api_key, target_domain):
    response = requests.get(
        API_URL,
        headers={
            "x-rapidapi-host": "google-ai-overviews.p.rapidapi.com",
            "x-rapidapi-key": api_key,
        },
        params={"query": query, "gl": "us", "hl": "en"},
        timeout=45,
    )
    response.raise_for_status()

    payload = response.json()
    if not isinstance(payload, dict):
        raise RuntimeError("The API response is not a JSON object.")

    data = payload.get("data")
    if payload.get("status") != 200 or not isinstance(data, dict):
        message = payload.get("description") or "Unexpected API response"
        raise RuntimeError(message)

    answer = data.get("ai_overview")
    sources = data.get("sources")
    if not isinstance(sources, list):
        sources = []

    matches = 

    if not isinstance(answer, str) or not answer.strip():
        state = "no_overview"
    elif matches:
        state = "cited"
    elif not sources:
        state = "no_sources"
    else:
        state = "not_cited"

    return {"query": query, "state": state, "matches": matches}


def main():
    api_key = os.environ.get("RAPIDAPI_KEY")
    if not api_key:
        raise RuntimeError("Set the RAPIDAPI_KEY environment variable first.")

    for query in QUERIES:
        try:
            result = check_query(query, api_key, TARGET_DOMAIN)
        except (requests.RequestException, RuntimeError) as error:
            print(f"\n{query}: request_failed ({error})")
            continue

        print(f"\n{query}: {result['state']}")
        for source in result["matches"]:
            print(f"- {source.get('url', 'URL missing')}")


if __name__ == "__main__":
    main()

Install the dependency with python -m pip install requests. Set RAPIDAPI_KEY in your terminal, replace TARGET_DOMAIN and QUERIES, then run the file. On PowerShell, set the key with $env:RAPIDAPI_KEY="your-key".

Run the checker against live JSON

Keep five result states separate

StateMeaningNext action
citedAt least one valid source matches the target domainStore every matching URL
not_citedAn answer and sources exist, but no source matchesKeep the completed observation
no_sourcesAn answer exists without a usable source listStore an empty citation list
no_overviewNo usable AI Overview answer was returnedRecord that the query was checked
request_failedThe request timed out, returned an HTTP error, or broke the expected contractRetry when appropriate and preserve the error

The distinction matters when you calculate a citation rate. Use completed checks with an actual overview as the denominator. Report no-overview and failed requests separately so they cannot improve or damage the percentage by accident.

Store evidence instead of one Boolean

A useful record contains the query, gl, hl, observation time, result state, answer, full source list, and matched URLs. Keep the returned source URL even if you later resolve its redirects.

Do not overwrite yesterday's result. Google explains that AI Overviews appear only when its systems decide they add value to classic Search, and the returned links can vary. One current Boolean cannot show when a citation appeared or disappeared.

Your monthly request count is:

queries * countries * languages * checks per month

For example, 50 queries checked in two countries once a week require about 50 * 2 * 1 * 4 = 400 requests per month. Calculate this before choosing an API plan.

Can Search Console replace the API check?

No. Search Console reports performance and visibility for your verified property. The API check answers a narrower question: which source pages appeared in one captured AI Overview response. Search Console does not provide the full competing source list returned by this endpoint.

Use Search Console to understand impressions, clicks, and search visibility. Use the API dataset when you need query-level citation evidence with the returned source URLs.

For every response field and error state, read the Google AI Overviews API response guide. To compare several domains, continue with the AI Overview competitor monitor.

Frequently asked questions

Does one match prove broad AI Overview visibility?

No. It proves one citation for one query, country, language, and check time. Broader conclusions need a defined query set and repeated checks.

Should subdomains count?

Decide before collecting results. Documentation sites often want docs.example.com included under example.com. A marketplace comparing independent hosts may require exact matching.

Should the checker follow redirects?

Keep the URL returned by the API as the original evidence. If redirects matter, resolve them in a separate step and store both URLs.

How often should it run?

Match the schedule to your decision. A weekly content review rarely needs hourly checks. Use the request formula above before increasing frequency.

Sources and verification dates

The response field names and temporary error behavior referenced in this guide come from a live product test performed on August 5, 2026. They are dated observations, not guarantees about future responses.

Check your first domain and save the result