Fetching AI Overviews with Node.js
AI Overviews are quickly becoming a prominent feature in today’s SEO landscape, and with SerpApi, extracting this data is simple.
While Google hasn’t shared many details about how sources are selected for AI Overviews, early signs suggest that they rely on many of the same SEO principles already in use. This makes tracking AI Overviews a valuable addition to your SEO strategy, offering insight into how users discover and interact with your content.
By targeting the correct queries and optimizing your content accordingly, you may improve your chances of being cited in an AI Overview. And although SerpApi simplifies data collection, there are a few common pitfalls to be aware of. In this post, I’ll walk through what to expect and how to avoid issues during implementation.
Getting Started
For this guide, I'll be using SerpApi's Node.js package (documentation) to retrieve AI Overviews. That said, the same principles apply no matter which programming language you prefer.
I also recommend reviewing the SerpApi Google Search API and AI Overview API documentation to get more familiar with the endpoints and data structure.
Requirements
- SerpApi API Key - If you don’t have an account yet, you can sign up for a free plan with 100 searches per month. If you already have an account, your API key is available in your dashboard.
- Node.js 7.10.1 or newer
- SerpApi Node.js Package - You can install it using
npm install serpapi
Search Parameters
AI Overviews are returned for some queries to SerpApi's Google Search API. To get started, let’s define the search parameters:
const searchParams = {
engine: "google",
q: query,
api_key: API_KEY,
no_cache: true,
};
Search Parameters
Here’s what each parameter does:
engine : "google"
- Tells SerpApi to use the standard Google Search engine.q: query
- The search query to submit.api_key: API_KEY
- Your SerpApi key for authentication.no_cache: true
- Forces SerpApi to fetch fresh data from Google instead of returning a cached result.
no_cache
is not used, you may receive a cached response that includes an expired page_token
. Always use no_cache: true
when you intend to follow up with a second request using the page_token
.Perform the Initial Search and Check for AI Overview
const searchResponse = await getJson(searchParams);
const overviewData = searchResponse.ai_overview;
Request
This performs the initial search and attempts to extract the ai_overview
object from the response. If the query triggers an AI Overview, the overviewData
the variable will contain its content; otherwise, it will be undefined.
page_token
, which is a temporary reference used to fetch the actual AI Overview in a second request.Check for page_token
and Fetch the Full AI Overview
if (overviewData.page_token) {
const overviewParams = {
engine: "google_ai_overview",
api_key: API_KEY,
};
overviewParams.page_token = overviewData.page_token;
const ai_overview_response = await getJson(overviewParams);
overviewResult = ai_overview_response.ai_overview;
} else {
overviewResult = overviewData;
}
Additional request
This checks whether the initial response includes a page_token
. If it does:
- A second request is made using the
google_ai_overview
engine and thepage_token
. - The full AI Overview is returned and stored in
overviewResult
.
If no token is found, it assumes the AI Overview was included in the original response.
page_token
values are short-lived, expiring within ~4 minutes. You must make the follow-up request immediately.Full Example
In the example below, we iterate over an array of queries, performing a Google Search for each one and checking if an AI Overview is returned.
If an AI Overview is present, we then check whether it includes a page_token
. If it does, we make a follow-up request to the google_ai_overview
engine using that token to retrieve the full AI Overview.
import { getJson } from "serpapi";
import dotenv from "dotenv";
dotenv.config();
const API_KEY = process.env.SERPAPI_KEY;
const queries = [
"what makes a good web hosting service",
"best crm platform",
"top programming languages to learn in 2025",
];
const fetchAIOverview = async (query) => {
const searchParams = {
engine: "google",
q: query,
api_key: API_KEY,
no_cache: true,
};
try {
const searchResponse = await getJson(searchParams);
const overviewData = searchResponse.ai_overview;
let overviewResult;
if (!overviewData) {
console.log("No AI overview available.");
return;
}
if (overviewData.page_token) {
const overviewParams = {
engine: "google_ai_overview",
api_key: API_KEY,
};
console.log("Page token found. Fetching AI overview page...");
overviewParams.page_token = overviewData.page_token;
const ai_overview_response = await getJson(overviewParams);
console.log("AI overview retrieved.");
overviewResult = ai_overview_response.ai_overview;
} else {
console.log("AI overview retrieved.");
overviewResult = overviewData;
}
console.log("AI Overview:\n", overviewResult);
} catch (error) {
console.error("Error fetching data from SerpAPI:", error);
}
};
queries.forEach((query) => {
console.log(`Fetching AI overview for query: "${query}"`);
fetchAIOverview(query);
});
Full code example
Best Practices Summary
- Use
no_cache
: true to avoid stale results and expired tokens. - Make the follow-up request to
google_ai_overview
immediately if apage_token
is present. - Process each query sequentially, not in parallel, to avoid expired
page_tokens
.
Resources
For a high-level introduction to the Google AI Overviews API, I recommend checking out the following blog post:
If you have questions or run into any issues with AI Overviews, don’t hesitate to reach out to SerpApi’s support team at contact@serpapi.com