DEV Community

dodou
dodou

Posted on

Tracking Google Featured Snippets with a SERP API

Featured snippets are the "position zero" of Google — the answer card above the organic results. If you own it, you win the click without being #1. If you lose it, your traffic drops overnight.

The annoying part: snippets come and go, and Google doesn't tell you when. This post shows how to track them programmatically with a SERP API, so you get an alert the day your snippet changes.

The key insight

Most search APIs return organic results, but the interesting part for snippet tracking is the featured_snippet module — which is only present when Google actually shows a snippet for that query. That presence/absence is itself the signal you want to watch.

The API I'm using here is SerpBase (https://api.serpbase.dev). Its /google/search endpoint returns featured_snippet alongside organic when Google renders one:

import requests

resp = requests.post(
    "https://api.serpbase.dev/google/search",
    headers={"Content-Type": "application/json", "X-API-Key": "your_api_key"},
    json={"q": "python asyncio", "hl": "en", "gl": "us"},
)
data = resp.json()

snippet = data.get("featured_snippet")
if snippet:
    print("Snippet found:", snippet.get("title"))
    print("Answer:", snippet.get("answer") or snippet.get("snippet"))
    print("Source:", snippet.get("link"))
else:
    print("No snippet for this query right now")
Enter fullscreen mode Exit fullscreen mode

What a snippet response looks like

When present, featured_snippet carries the answer card content:

{
  "title": "asyncio — Asynchronous I/O",
  "answer": "asyncio is a library to write concurrent code using the async/await syntax...",
  "link": "https://docs.python.org/3/library/asyncio.html",
  "source": "docs.python.org"
}
Enter fullscreen mode Exit fullscreen mode

Note that some queries have no snippet at all — a plain "did we win position zero or not" signal, which is exactly what you want to track day over day.

Building the tracker

The pattern: run the query daily, record whether a snippet exists, and alert on changes.

import sqlite3, datetime, requests

API_KEY = "your_api_key"
BASE = "https://api.serpbase.dev"
YOUR_DOMAIN = "example.com"

KEYWORDS = ["python asyncio", "serp api", "google search api"]

con = sqlite3.connect("snippet.db")
con.execute("""CREATE TABLE IF NOT EXISTS snippet_state (
    keyword TEXT, day TEXT,
    snippet_owned INTEGER,           -- 1 = we own the snippet
    snippet_present INTEGER,         -- 1 = someone has a snippet
    snippet_source TEXT,
    PRIMARY KEY (keyword, day)
)""")

def check_snippet(kw):
    resp = requests.post(
        f"{BASE}/google/search",
        headers={"Content-Type": "application/json", "X-API-Key": API_KEY},
        json={"q": kw, "hl": "en", "gl": "us"},
    ).json()
    sn = resp.get("featured_snippet")
    present = 1 if sn else 0
    owned = 1 if (sn and YOUR_DOMAIN in (sn.get("link", ""))) else 0
    return present, owned, (sn or {}).get("link")

for kw in KEYWORDS:
    present, owned, source = check_snippet(kw)
    con.execute(
        "INSERT INTO snippet_state VALUES (?, ?, ?, ?, ?)",
        (kw, datetime.date.today().isoformat(), owned, present, source),
    )
con.commit()
Enter fullscreen mode Exit fullscreen mode

Alerting on change

The value comes from the diff: today vs yesterday.

today = dict(con.execute(
    "SELECT keyword, snippet_owned FROM snippet_state WHERE day = ?",
    (datetime.date.today().isoformat(),),
).fetchall())

yesterday = dict(con.execute(
    "SELECT keyword, snippet_owned FROM snippet_state WHERE day = ?",
    (datetime.date.today() - datetime.timedelta(days=1),),
).fetchall())

for kw, owned_now in today.items():
    owned_prev = yesterday.get(kw)
    if owned_prev is not None and owned_now != owned_prev:
        action = "WON" if owned_now else "LOST"
        print(f"[{action}] {kw} featured snippet — notify the team")   # hook to Slack here
Enter fullscreen mode Exit fullscreen mode

Now you know the day you lost (or won) position zero, instead of discovering it in next month's traffic report.

Beyond snippets: the same response has more

The featured_snippet module is one of several that come back when Google renders them:

  • people_also_ask — the PAA box questions, useful for content gaps
  • related_searches — keyword expansion material
  • knowledge_graph — entity panel data

All in the same response, no extra requests.

Cost note

/google/search costs 1 credit per request. Tracking 20 keywords daily = 600 requests/month, which on a standard pack (~$0.50/1k) is around $0.30/month. The free 100 searches on signup cover your first test week, and there's no monthly fee to carry while you build.

Wrapping up

Featured snippet tracking is just "run the query, read the featured_snippet module, diff day over day." Ten lines of code, and you finally get notified when position zero changes hands.

The full response schema (including all optional modules) is in the SerpBase documentation. Run the snippet check against your own keywords and see who owns position zero today.

Top comments (0)