# Google SERP + AI Overviews API (`subimpact/google-serp-ai-overviews`) Actor

SerpAPI-style Google search JSON: AI Overview text + citations + organic results in one clean response per query. Batch up to 1000 queries per run.

- **URL**: https://apify.com/subimpact/google-serp-ai-overviews.md
- **Developed by:** [subimpact](https://apify.com/subimpact) (community)
- **Categories:** AI, Developer tools, SEO tools
- **Stats:** 5 total users, 4 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 search completeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Google SERP + AI Overviews API

SerpAPI-style Google search JSON — **AI Overview answer + citations + organic results + knowledge graph + top stories + local results in one response per query**, at a fraction of the cost.

- **Batch up to 1000 queries** per run (array input, one API call) — processed with 10-way concurrency (configurable 1–30), rows stream to the dataset as they complete (a timed-out run still delivers partial results)
- **AI Overview** parsed into structured `text_blocks` (paragraphs, headings, lists) + `references` (citation title + link + snippet) — including **deferred AIOs** Google generates asynchronously (resolved via Google's own `/async/folsrch` endpoint, no browser rendering, no third-party API)
- **Rich SERP surface**: organic results, knowledge graph (facts), top stories, local results (rating/reviews), People Also Ask, discussions & forums
- **Geo targeting** via `location` (e.g. "New York, NY", "Kuala Lumpur") — Google uule encoding, same as SerpAPI
- Country (`gl`) + language (`hl`) targeting
- **Pay per search** — $0.005 per completed query (badge $5.00 / 1,000 searches). Queries that return no parseable content (status `Empty`) or error out are **not charged**.
- Buyer pays platform usage on top (~$0.004/query) — **~$0.009 all-in per query**, ~$1.05 for 120 queries

### Input

```json
{
  "queries": ["best crm for startups", "what is retrieval augmented generation"],
  "gl": "us",
  "hl": "en",
  "maxResults": 10,
  "location": "New York, NY",
  "retryDeferredAIO": true,
  "retryDeferredMaxFetches": 2,
  "captureRawHtml": false,
  "concurrency": 10,
  "retryDeferredPoll": false
}
```

| Field | Type | Default | Description |
|---|---|---|---|
| `queries` | array of strings | required | Search queries (max 1000 per run) |
| `gl` | string | `us` | Two-letter country code (us, my, uk, sg…) |
| `hl` | string | `en` | Two-letter language code (en, ms, zh…) |
| `maxResults` | integer | `10` | Max organic results per query (1–10) |
| `location` | string | (proxy IP geo) | Geo target, e.g. "New York, NY". Google uule-encoded server-side. |
| `retryDeferredAIO` | boolean | `true` | Resolve deferred AI Overviews (Google generates some answers asynchronously). Uses the embedded `/async/folsrch` template via a datacenter proxy. Extra cost only on affected queries. `false` = always single fetch. |
| `retryDeferredMaxFetches` | integer | `2` | Max total fetches per query when a deferred AI Overview shell is detected (1–5). `1` = single fetch, same as `retryDeferredAIO: false`. |
| `captureRawHtml` | boolean | `false` | Save the raw SERP HTML for every query to the key-value store (key `raw-<query>-<ts>.html`). For building golden test corpora / debugging selector drift. Adds ~200–400KB per query to KV storage. |
| `concurrency` | integer | `10` | Parallel queries (1–30). A/B measured: c5=34s, c10=35s, c20=65s for 20 queries — the SERP proxy pool is the bottleneck, so beyond ~10 workers latency balloons. 10 = same throughput as 5 with headroom for AIO-heavy sets. |
| `retryDeferredPoll` | boolean | `false` | Legacy poll re-fetch for deferred AIOs (re-fetch up to `retryDeferredMaxFetches` times, keep richest). Off by default — folsrch resolves 90%+ of deferred AIOs; the poll recovered 0/120 in the stress test. Enable only if folsrch regresses. |

### Output

One dataset item per query:

```json
{
  "ai_overview": {
    "text_blocks": [
      { "type": "paragraph", "snippet": "The best CRM for a startup depends on your core workflow…" },
      { "type": "list", "list": [{ "title": "…" }] }
    ],
    "references": [
      { "title": "CRM for Startups: Free Software to Scale Your Business", "link": "https://www.hubspot.com/products/crm/startups", "snippet": "…", "index": 0 }
    ],
    "resolved_by": "folsrch"
  },
  "organic_results": [
    { "position": 1, "title": "…", "url": "https://…", "displayed_link": "…", "snippet": "…" }
  ],
  "people_also_ask": ["…", "…"],
  "search_metadata": { "status": "Success", "created_at": "…", "total_time_taken_ms": 3088, "google_url": "…" },
  "search_parameters": { "q": "best crm for startups", "gl": "us", "hl": "en", "location": "New York, NY" },
  "knowledge_graph": {
    "title": "…",
    "description": "…",
    "source": { "name": "Wikipedia", "link": "…" },
    "facts": [{ "label": "Born", "value": "…" }]
  },
  "top_stories": [ { "title": "…", "url": "…", "source": "The Economist" } ],
  "local_results": [ { "title": "…", "rating": "4.9", "reviews": 534 } ],
  "discussions_and_forums": [ { "title": "…", "url": "…", "source": "reddit" } ],
  "selector_strategy": {
    "organic_results": "primary",
    "people_also_ask": "primary",
    "knowledge_graph": "fallback",
    "top_stories": "structural",
    "local_results": "primary",
    "discussions_and_forums": "primary"
  }
}
```

- `ai_overview.resolved_by` is `folsrch` (deferred answer resolved via Google's async endpoint), `poll` (recovered via re-fetch), or absent (answer was inline in the SERP).
- Modules are `null` when Google returns none for that query.
- `search_metadata.status` is `Success` (content parsed), `Empty` (no parseable content — not charged), or `Error` (fetch failed after retries — not charged).
- `search_metadata.drift_evidence` (present only on `Empty` rows) is the key of the raw HTML sample saved to the actor's key-value store — grab it for instant diagnosis of selector drift.
- `selector_strategy` records which parser strategy fired per module: `primary` (current Google classes), `fallback` (stable anchors), or `structural` (class-free heuristics). `primary` everywhere = healthy; `fallback`/`structural` = Google rotated classes but results still parse.
- `ads` and `related_searches` are **not included** — the Google SERP proxy serves a server-rendered variant where those JS-only modules are absent (verified: the `tads` ad container arrives empty, "Sponsored" labels never appear). This keeps results clean and ad-free.
- **No pagination field** — each query returns page 1 results; batch more queries for broader coverage.

### Pricing

- **$0.005 per completed query** (pay-per-event, `search-completed`)
- Platform usage billed on top, paid by the user: Google SERP proxy ~$0.0025/query + compute ~$0.0015/query (amortized at batch scale)
- Deferred-AIO resolution adds a shell re-fetch + a datacenter proxy call on affected queries only — the datacenter leg is not billed as SERP usage
- **All-in ≈ $0.009 per query** → **120 queries ≈ $1.05**
- vs the leading AI-Overview-only alternative: ~$1.81 for the same 120 queries
- Note: tiny runs (1–5 queries) pay ~$0.02–0.03/query effective due to container cold start — batch ≥25 for best economics

### Use cases

- **AEO/GEO monitoring** — track whether your brand appears in AI Overviews and which sources Google cites, per market with `location`
- SEO rank tracking at scale
- Research / data collection for LLM training sets
- Competitive SERP intelligence

### Costs & limits

- 1000 queries max per run (bump the array; batch in chunks for more)
- Each query = 1 Google SERP request through Apify's Google SERP proxy (+ up to 2 extra requests only when Google defers the AI Overview)
- 10-way concurrency (default): 1000 queries ≈ 30 min (fits the 7200s timeout); rows stream to the dataset as they complete. A/B measured: c5=34s, c10=35s, c20=65s for 20 queries — the SERP proxy pool is the bottleneck, so beyond ~10 workers latency balloons. Set `concurrency` lower (e.g. 5) for gentler load.
- 7200s timeout (2h), 4096 MB memory
- **Build tags:** the actor runs the `stable` build by default (verified, production-hardened). New builds are pushed to `latest` and promoted to `stable` only after verification — buyers are never exposed to unverified code.

# Actor input Schema

## `queries` (type: `array`):

List of search queries to run. Max 1000 per run.

## `gl` (type: `string`):

Two-letter country code for Google results, e.g. us, my, uk, sg.

## `hl` (type: `string`):

Two-letter language code, e.g. en, ms, zh.

## `maxResults` (type: `integer`):

How many organic results to return per query (1-10, default 10).

## `location` (type: `string`):

Geo target for results, e.g. "New York, NY" or "Kuala Lumpur". Empty = Google uses proxy IP geolocation. Encoded server-side via Google uule (same as SerpAPI).

## `retryDeferredAIO` (type: `boolean`):

Google generates AI Overviews asynchronously — the first fetch sometimes returns only a placeholder shell. When true, the actor re-fetches (up to retryDeferredMaxFetches total) and keeps the richest response. Each retry costs one extra proxy request (~$0.0025) + compute on affected queries only. Set false to always use a single fetch per query.

## `retryDeferredMaxFetches` (type: `integer`):

Upper bound on total fetches per query when a deferred AI Overview shell is detected. 1 = single fetch (same as retryDeferredAIO=false). Higher = better recovery odds, more proxy usage on affected queries. Range 1-5.

## `captureRawHtml` (type: `boolean`):

When true, saves the raw SERP HTML for every query to the key-value store (key: raw-<query>-<ts>.html). Used for building golden test corpora and debugging selector drift. Adds ~200-400KB per query to KV storage. Default false.

## `concurrency` (type: `integer`):

Number of parallel queries (1-30, default 10). A/B measured: 20 queries at c5=34s, c10=35s, c20=65s — the SERP proxy pool is the bottleneck, so beyond ~10 workers latency balloons. 10 gives the same throughput as 5 with headroom for AI-Overview-heavy sets.

## `retryDeferredPoll` (type: `boolean`):

When true, re-fetches the SERP up to retryDeferredMaxFetches times when a deferred AI Overview shell is detected, keeping the richest response. Off by default: the folsrch recovery path resolves 90%+ of deferred AIOs, and the poll recovered 0/120 in the stress test while costing ~10s + extra proxy requests per shell query. Enable only if folsrch regresses.

## Actor input object example

```json
{
  "queries": [
    "best crm for startups"
  ],
  "gl": "us",
  "hl": "en",
  "maxResults": 10,
  "location": "",
  "retryDeferredAIO": true,
  "retryDeferredMaxFetches": 2,
  "captureRawHtml": false,
  "concurrency": 10,
  "retryDeferredPoll": false
}
```

# Actor output Schema

## `results` (type: `string`):

One dataset item per query: search\_parameters echo, ai\_overview with text\_blocks and references, organic\_results with title, url, displayed\_link, snippet, plus knowledge\_graph, top\_stories, local\_results, people\_also\_ask, discussions\_and\_forums, and selector\_strategy drift telemetry.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "best crm for startups"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("subimpact/google-serp-ai-overviews").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "queries": ["best crm for startups"] }

# Run the Actor and wait for it to finish
run = client.actor("subimpact/google-serp-ai-overviews").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "best crm for startups"
  ]
}' |
apify call subimpact/google-serp-ai-overviews --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,subimpact/google-serp-ai-overviews"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/eDJ3cPv3MbIAoCYHg/builds/BV1EttJQvz9BKhZuD/openapi.json
