Which of Your Keywords Trigger an AI Overview? Build an Exposure Audit

By Serpent API Team · · 11 min read

Not all of your keywords are in danger. Some sit on plain old SERPs that still send clicks the way they always did. Others now sit under an AI Overview that answers the query before anyone scrolls to your link — and on those, position-one CTR can fall by as much as 58%.

The problem is you can't see which is which from a rankings report. A keyword can hold position 3 and still bleed traffic because an AI Overview ate the top of the page. Before you can defend your traffic, you need a map of where the exposure actually is.

This guide builds that map: a Python audit that runs your keyword list, flags which ones show an AI Overview, checks whether you're cited inside it, and puts a dollar figure on the traffic at risk. If you want the extraction mechanics in more depth first, see extracting Google AI Overviews via API.

Why an exposure audit beats a rankings report

Rankings answer "where do I sit?" An exposure audit answers "does my position still earn the clicks it used to?" In 2026 those are different questions. With AI Overviews present, the average organic CTR drop is around 18%, and far worse at the top of the page. The categories most exposed — health, technology, recipes — are exactly the ones where AI can summarize an answer confidently and the user never needs to click.

So the audit sorts your keywords into three buckets:

No AI Overview Traffic intact Lowest priority AIO + cited Some loss, ~+35% on surviving clicks AIO + replaced Biggest CTR loss Fix these first

Step 1: Detect the AI Overview

The Google SERP API returns an aiOverview block when one is present. Checking for it is the whole detection step:

import os, requests

KEY = os.environ["SERPENT_API_KEY"]

def fetch(q):
    r = requests.get("https://apiserpent.com/api/search",
        params={"q": q, "country": "us"},
        headers={"X-API-Key": KEY}, timeout=90)
    r.raise_for_status()
    return r.json().get("results", {})

def has_aio(results):
    aio = results.get("aiOverview")
    return bool(aio and aio.get("text"))

Step 2: Are you cited or replaced?

An AI Overview that cites you is a very different outcome from one that replaces you. Being cited can actually lift clicks by around 35% versus being absent. So we check the overview's source list for your domain:

def cited_in_aio(results, domain):
    aio = results.get("aiOverview") or {}
    return any(domain in (s.get("url") or "")
               for s in aio.get("sources", []))

Step 3: Quantify traffic at risk

Now the part executives care about. For each exposed keyword, multiply your monthly clicks by an estimated CTR-loss factor. Use a conservative loss when you're cited and a steeper one when you're replaced:

# conservative CTR-loss assumptions you can tune
LOSS_REPLACED = 0.45   # overview present, you are NOT cited
LOSS_CITED    = 0.15   # overview present, you ARE cited

def at_risk(monthly_clicks, exposed, cited):
    if not exposed:
        return 0
    return round(monthly_clicks * (LOSS_CITED if cited else LOSS_REPLACED))

Need the keyword + clicks data? Pull your queries and impressions from Google Search Console, then feed them to this audit. The Google SERP API supplies the live AI Overview block. See pricing →

The full audit script

Feed it a CSV of keyword,monthly_clicks (export it straight from Search Console) and it prints a prioritized report:

import os, csv, requests

KEY = os.environ["SERPENT_API_KEY"]
DOMAIN = "yourdomain.com"
LOSS_REPLACED, LOSS_CITED = 0.45, 0.15

def fetch(q):
    r = requests.get("https://apiserpent.com/api/search",
        params={"q": q, "country": "us"},
        headers={"X-API-Key": KEY}, timeout=90)
    r.raise_for_status()
    return r.json().get("results", {})

def audit(path):
    rows = []
    with open(path) as f:
        for kw, clicks in csv.reader(f):
            res = fetch(kw)
            aio = res.get("aiOverview") or {}
            exposed = bool(aio.get("text"))
            cited = any(DOMAIN in (s.get("url") or "")
                        for s in aio.get("sources", []))
            clicks = int(clicks)
            risk = 0 if not exposed else round(
                clicks * (LOSS_CITED if cited else LOSS_REPLACED))
            rows.append((kw, clicks, exposed, cited, risk))
            print(f"  {kw[:38]:38} aio={exposed!s:5} cited={cited!s:5} risk={risk}")
    rows.sort(key=lambda r: r[4], reverse=True)
    total = sum(r[4] for r in rows)
    print(f"\n=== Exposure audit for {DOMAIN} ===")
    print(f"Keywords scanned: {len(rows)}")
    print(f"Showing an AI Overview: {sum(1 for r in rows if r[2])}")
    print(f"Overview present, you NOT cited: {sum(1 for r in rows if r[2] and not r[3])}")
    print(f"Estimated monthly clicks at risk: {total:,}")
    print("\nTop 10 at-risk keywords:")
    for kw, c, e, ci, risk in rows[:10]:
        tag = "REPLACED" if (e and not ci) else ("cited" if e else "safe")
        print(f"  {risk:6,}  {tag:8}  {kw}")

if __name__ == "__main__":
    audit("keywords.csv")

What to do with the report

The output gives you a ranked to-do list instead of a vague worry:

"Replaced" keywords, high clicks — fix first. These are pages where an AI Overview answers the query and doesn't even cite you. Restructure the content to be the cleanest answer to the exact question, add the supporting data the overview would want, and tighten your structured data so you become a citation candidate.

"Cited" keywords — protect and expand. You're already a source. Keep that content fresh and make sure the surviving click leads somewhere that converts, since those visitors arrive pre-informed and higher-intent.

"Safe" keywords — harvest while you can. No overview today doesn't mean none tomorrow. These are your reliable traffic; make the most of them and re-check next month.

Pair this with The Great Decoupling to connect the exposure map to your actual analytics, and with pixel position vs rank to understand how far AI Overviews physically push your listing down the page.

FAQ

How do I know if a keyword shows an AI Overview?

Query it through the SERP API and check for a non-empty aiOverview block in the response. If it's there, Google is showing an overview and your organic listing is pushed down.

How much traffic do AI Overviews cost?

Around 18% average organic CTR drop when one appears, up to ~58% for position one on some query types. Health, tech, and recipe queries are most exposed.

Is high exposure always bad?

No — being cited inside the overview can lift CTR ~35% vs not being cited, and surviving clicks convert better. The audit separates "cited" from "replaced" so you act on the right ones.

How often should I re-run it?

Monthly for most sites; sooner after a big content change or a Google ranking update.

Audit Your AI Overview Exposure

The Google SERP API returns the live AI Overview block and its sources as clean JSON — everything this audit needs. 100 free quick-search calls on signup.

Get Your Free API Key

Explore: Google SERP API · Pixel Position API · Playground · Docs