# Google AI Overview & Perplexity Visibility Tracker (`tugelbay/google-ai-overview-tracker`) Actor

Track Google AI Overviews and Perplexity answers for chosen prompts. Export answer status, available source domains, brand and competitor mentions, and dated evidence for AI search visibility reports.

- **URL**: https://apify.com/tugelbay/google-ai-overview-tracker.md
- **Developed by:** [Tugelbay Konabayev](https://apify.com/tugelbay) (community)
- **Categories:** AI, SEO tools, Marketing
- **Features:** Limited permissions
- **Stats:** 50 total users, 5 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.00 / 1,000 prompt checks

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

[![Google AI Overview tracker for AI visibility prompts](https://api.apify.com/v2/key-value-stores/bplRdpnd85eGQkW1N/records/google-ai-overview-tracker-hero.png)](https://apify.com/tugelbay/google-ai-overview-tracker)

[![Google AI Overview prompt input to AI visibility dataset](https://api.apify.com/v2/key-value-stores/bplRdpnd85eGQkW1N/records/google-ai-overview-tracker-input-output.png)](https://apify.com/tugelbay/google-ai-overview-tracker)

[![Google AI Overview source domain dataset preview](https://api.apify.com/v2/key-value-stores/bplRdpnd85eGQkW1N/records/google-ai-overview-tracker-dataset-preview.png)](https://apify.com/tugelbay/google-ai-overview-tracker)

Google AI Overview & Perplexity Visibility Tracker checks selected prompts in either Google AI Overviews or Perplexity. It records answer status, available source domains, and brand, domain, or competitor mentions for SEO, GEO, AEO, and AI search visibility reports.

Use it as a lightweight Google AI Overview visibility tracker: prompt in, AIO status out, with answer text, source domains, brand mentions, domain citation checks, competitor mentions, and a clean `aiOverviewAvailable=false` result when Google does not show an AI Overview.

This actor supports **Google AI Overview and Perplexity**, selected with the `engine` input field. It does not claim ChatGPT, Gemini, Claude, Copilot, Grok, or Meta AI coverage — those engines are not yet validated for reliable, login-free extraction.

For implementation notes, examples, and SEO/GEO use cases, see the <a href="https://konabayev.com/tools/google-ai-overview-tracker/?utm_source=apify_readme&utm_medium=referral&utm_campaign=google-ai-overview-tracker" rel="nofollow sponsored">Google AI Overview Tracker guide</a>.

> **Use when:** weekly AI visibility monitoring for commercial prompts, client reporting, SEO/GEO dashboards, and source-domain gap analysis.
> **Default run:** a 5-prompt monitoring pack that produces one row per prompt, with visibility status and score fields ready for dashboards.
> **Pricing:** pay per prompt checked. A Google row, and a Perplexity row that has finished answer prose plus at least one citation, uses the SDK store-then-charge operation for one `prompt-check` event. A Perplexity row that is empty, still showing page chrome or `Working`, under the answer-length gate, or without citations is delivered and counted unresolved, and does not emit `prompt-check`. Run spending limits can stop delivery; failed persistence is not charged by this operation.
> **Plan parity:** free and paid Apify users use the same prompt limits, fields, timeout and retry policy. There is no Actor monthly quota. Run spending limits and the shared maximum of 50 prompts still apply. Upstream blocking can prevent an observation on either plan; inspect engineStatus and RUN_REPORT.

An explicit upstream refusal is not retried. After delivering the current concurrency batch, the Actor stops later checks and records `stoppedReason=source_refused`, requested and undelivered check counts in `RUN_REPORT`. A Perplexity Cloudflare challenge is not that refusal: the browser waits for the challenge to clear, then tries one new residential session before marking the row blocked, and later prompts still run. A blocked check is unavailable, not evidence that your brand has zero visibility. At most the already-started concurrency batch can finish after a hard refusal.

If a citation redirect refuses access after an answer was acquired, `answerText` and known direct `sourceLinks` from that response are retained. `aiOverviewAvailable` may still be true, while `engineStatus=blocked`, `measurementComplete=false`, `citationLinksComplete=false`, and `visibilityScore=0`; later batches still stop. Opaque supported Google citation wrappers that cannot be decoded are counted as unresolved, without adding redirect requests. `RUN_REPORT.answersWithText` includes retained partial or blocked answers; these do not count as completed measurements.

### Why use this AI search visibility Actor?

- Monitor a fixed prompt set on a schedule instead of checking answers manually.
- Separate `no_ai_overview`, source gaps, competitor visibility, blocks, and timeouts in structured rows.
- Preserve `checkedAt`, source domains, target-brand detection, and run status for auditable reporting.
- Export the same schema to datasets, webhooks, spreadsheets, and BI tools.

### How to run a monitoring check

1. Start with one to five commercial prompts, a target brand, and target domain.
2. Keep concurrency at `1`, inspect `engineStatus`, `visibilityStatus`, and source links, then refine the prompt set.
3. Schedule the validated prompt set and compare dated rows; do not interpret one volatile SERP as a durable ranking.

### Engines

Set the `engine` input field to choose which AI answer surface to check:

| Engine              | `engine` value       | Country/language              | Notes                                                                 |
| -------------------- | --------------------- | ------------------------------ | ---------------------------------------------------------------------- |
| Google AI Overview   | `google_ai_overview`  | Uses `country` and `language` | Default. Dedicated Apify SERP HTTP service; scoped AIO and deferred continuation. |
| Perplexity           | `perplexity`          | Ignored — always English      | Residential browser on `perplexity.ai/search?q=...`. A Cloudflare challenge is waited out and retried once on a new session. A hard refusal still stops later prompts. |

Both engines share the same output shape (`answerText`, `sourceLinks`, `targetBrandMentioned`, `visibilityStatus`, and so on), so existing dashboards and reports work unchanged when you add Perplexity prompts — only `queryUrl`/`answerUrl` and the absence of country/language targeting differ. Run Google and Perplexity checks for the same prompt list as two separate actor runs (one per `engine` value) to compare visibility across both surfaces.

### Commercial Workflows This Targets

Use this actor when AI visibility, answer engine optimization, or Google AI Overview reporting maps to a real workflow:

- weekly Google AI Overview checks for commercial prompt lists
- answer engine optimization and AI search visibility reporting
- source-domain analysis for readable links inside Google AI answers
- client SEO/GEO dashboards for agencies and consultants
- brand/domain/competitor visibility monitoring across a stable prompt set

### Fast Answers

#### What is a Google AI Overview tracker?

A Google AI Overview tracker checks specific Google search prompts and records whether an AI Overview appears, what answer text was visible, which external source domains were extracted from its answer block, and whether your brand, target domain, or competitors appeared.

Google text and links are limited to the supported AI answer container. The Actor restores deferred answer fragments embedded in the response, including supported “Show more” content, without executing Google's JavaScript. Organic results, query text, citation labels and source-card snippets do not count as answer mentions. Unknown layouts fail explicitly. A continuation that cannot be recovered produces `partial_aio`, not a complete measurement.

Google uses one Apify Google SERP request per prompt, without a Google login or a separate provider key. There are no automatic Google search retries. `proxyConfiguration` applies only to the Perplexity browser. Citation destinations are resolved through Google redirect responses without fetching the external articles, with at most 30 unique links and a 15-second total redirect budget. An explicit refusal stops further resolution and later prompt batches.

Google rows add `answerTextComplete`, `citationLinksComplete`, `unresolvedCitationCount` and `measurementComplete`. `citationLinksComplete` describes resolution of the recognized links in the retrieved AIO, not independent proof that Google exposed every possible citation. Filter Google reports to `measurementComplete=true`. A false mention/citation flag on an incomplete row means “not observed”, not “absent”. Partial observations have `visibilityStatus=partial_aio` and score 0; this is a collection-quality status, not zero brand visibility. Answer text is bounded at 50,000 characters; hitting that limit also marks the row incomplete.

When recognized citation destinations remain unresolved, `error` includes reason counts such as `timeout`, `time_budget`, `candidate_limit`, `network_error`, `http_500`, `unsupported_redirect`, or `invalid_response`. These distinguish retrieval and parsing limits without exposing redirect URLs or raw response bodies. They do not change the completeness flags or request limits.

After normal dataset delivery, the default key-value store's `RUN_REPORT` records delivered checks, engine-status counts, completed versus unresolved checks, answer texts found and answers without extracted citation links. The final status also summarizes these counts. A `SUCCEEDED` run can contain blocked, timeout or error rows: inspect `engineStatus` and this report before using visibility scores. `completedChecks` includes a successfully observed absence of an answer; it does not mean every check produced an AI answer. Citation completeness is not independently verified. A run stopped by a billing or storage exception may not have a final report.

Brand and competitor matching is case-insensitive and requires the complete configured name at word boundaries: `Apple` does not match `Pineapple`. Whitespace is normalized. It is a literal-name heuristic, not entity recognition: aliases, translations and names embedded in unsegmented text may be missed.

#### Can this track AI visibility for SEO and GEO reports?

Yes. This actor is built for SEO, GEO, AEO, and AI visibility reporting where you need repeatable prompt checks, brand mention tracking, domain citation checks, competitor mention detection, and CSV/API-ready datasets.

#### Does it track ChatGPT, Gemini, or Claude?

Not yet. This actor tracks Google AI Overview and Perplexity, set via the `engine` input field. ChatGPT, Gemini, Claude, Copilot, Grok, and Meta AI are conversational UIs without a simple URL-query pattern, so they are not supported yet — that narrower scope keeps the output honest instead of mixing reliable and unvalidated engines.

### Starter monitoring run

Start with the 5-prompt monitoring pack below. Each Google prompt uses one SERP request and returns a dated observation with explicit completeness fields.

```json
{
  "prompts": [
    "best answer engine optimization tools",
    "best AI visibility tracker",
    "how to optimize for Google AI Overviews",
    "best GEO tools for SaaS SEO",
    "AI search visibility software"
  ],
  "brandName": "Semrush",
  "domain": "semrush.com",
  "competitors": ["Ahrefs", "Surfer SEO", "Conductor"],
  "country": "US",
  "language": "en",
  "maxPrompts": 5,
  "timeoutSeconds": 30,
  "maxConcurrency": 1
}
```

### What it returns

For each prompt, the actor returns one dataset item with:

- `aiOverviewAvailable` - whether Google displayed an AI Overview
- `answerText` - extracted AI Overview text when available
- `sourceLinks` and `sourceDomains` - external citation destinations from the supported AI answer block
- `targetBrandMentioned` - whether your brand appears in the AI Overview text
- `targetDomainCited` - whether your domain appears in source links
- `competitorMentions` - which competitor names appeared
- `visibilityStatus` and `visibilityScore` - dashboard-ready classification for owned, competitor, source-gap, no-AIO, blocked, timeout, or error outcomes
- `sourceCount` and `competitorCount` - quick numeric fields for BI tools and weekly reporting
- `engineStatus` - `ok_aio`, `ok_no_aio`, `partial_aio`, `blocked`, `timeout`, or `error`

If Google does not show an AI Overview for a prompt, the run still succeeds and returns `aiOverviewAvailable=false`.

### Larger input example

```json
{
  "prompts": [
    "best answer engine optimization tools",
    "best AI visibility tracker",
    "how to optimize for Google AI Overviews",
    "best GEO tools for SaaS SEO",
    "AI search visibility software",
    "LLM visibility platform",
    "best AEO software for agencies",
    "AI search optimization tools",
    "Google AI Overview monitoring",
    "AI visibility reporting software"
  ],
  "brandName": "Semrush",
  "domain": "semrush.com",
  "competitors": ["Ahrefs", "Surfer SEO", "Conductor"],
  "country": "US",
  "language": "en",
  "maxPrompts": 10,
  "timeoutSeconds": 30,
  "maxConcurrency": 1
}
```

For a quick validation, reduce `maxPrompts` to `1`. For a useful production report, keep the default 5 prompts or run 10-50 prompts weekly.

Free and paid Apify users have the same prompt limits and fields. There is no Actor monthly quota; the shared 50-prompt maximum and run spending limits still apply.

### Production monitoring workflow

Use the default 5-prompt pack to verify completed observations for your country/language and that the output fields fit your report. For production monitoring, use 10-50 prompts per run and schedule the task weekly.

Useful paid prompt sets usually come from:

- Google Search Console queries with commercial intent
- commercial search terms from ads, CRM notes, or sales calls
- category and reporting queries such as `answer engine optimization`, `ai search visibility`, and `llm visibility`
- "best X", "X alternatives", and "X vs Y" category prompts
- sales objections and buyer questions
- competitor pages and comparison pages

For agencies, create one Apify Task per client and send the dataset to Google Sheets, BigQuery, Slack, or a reporting webhook.

#### RSS feed for no-code monitoring

Every finished run can expose a lightweight RSS feed directly from its dataset. Replace `DATASET_ID` and use a scoped read-only token when the dataset is private:

```text
https://api.apify.com/v2/datasets/DATASET_ID/items?format=rss&fields=prompt,queryUrl&outputFields=title,link
```

This maps `prompt` to the RSS title and `queryUrl` to the link, so Feedly, Slack RSS apps, Zapier, Make, or n8n can watch new AI visibility checks without a custom integration. Never put an admin token into a public feed URL.

The actor processes prompts in concurrency-sized batches. If Apify reports that the run spending limit was reached, it stops charging and delivering immediately and does not launch another browser batch. Up to `maxConcurrency` checks from the current batch may already have finished internally, but unchargeable checks are not returned after the limit signal.

### Output example

```json
{
  "prompt": "best answer engine optimization tools",
  "engine": "google_ai_overview",
  "country": "US",
  "language": "en",
  "aiOverviewAvailable": true,
  "answerText": "AI Overview ...",
  "sourceDomains": ["semrush.com", "searchengineland.com", "ahrefs.com"],
  "targetBrand": "Semrush",
  "targetDomain": "semrush.com",
  "targetBrandMentioned": true,
  "targetDomainCited": true,
  "competitorMentions": ["Ahrefs", "Surfer SEO"],
  "visibilityStatus": "owned_visibility",
  "visibilityScore": 100,
  "sourceCount": 3,
  "competitorCount": 2,
  "engineStatus": "ok_aio",
  "runtimeSeconds": 3.2
}
```

### Output field reference

Each dataset item is one prompt check. The schema is intentionally flat enough for CSV, Google Sheets, webhooks, and BI dashboards, while still keeping source links and competitors as arrays for automation.

| Field                  | Type    | Description                                                                                                                          |
| ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `prompt`               | string  | The search prompt/query that was checked.                                                                                            |
| `engine`               | string  | `google_ai_overview` or `perplexity`, matching the input `engine` field.                                                             |
| `queryUrl`             | string  | Google Search with country/language parameters, or the Perplexity search URL. |
| `answerUrl`            | string  | Google search URL, or final Perplexity browser URL. |
| `country`              | string  | Google country code used for the check, for example `US`. Not applied for Perplexity.                                               |
| `language`             | string  | Google interface language, for example `en`. Not applied for Perplexity.                                                             |
| `aiOverviewAvailable`  | boolean | Whether an AI Overview block was detected.                                                                                           |
| `answerText`           | string  | Extracted AI Overview text when present; empty when no AIO was shown.                                                                |
| `sourceLinks`          | array   | External citation destinations from the supported AI answer block; Google redirects are resolved within a bounded budget. |
| `sourceDomains`        | array   | Deduplicated domains from `sourceLinks`.                                                                                             |
| `targetBrand`          | string  | Brand name supplied in input.                                                                                                        |
| `targetDomain`         | string  | Normalized target domain supplied in input.                                                                                          |
| `targetBrandMentioned` | boolean | Whether the brand name appears in the extracted AI Overview text.                                                                    |
| `targetDomainCited`    | boolean | Whether the target domain appears among extracted source domains.                                                                    |
| `competitorMentions`   | array   | Competitor names detected in extracted answer prose; organic SERP text is excluded. |
| `visibilityStatus`     | string  | Dashboard status such as `owned_visibility`, `competitor_visible`, `source_gap`, `no_ai_overview`, `blocked`, `timeout`, or `error`. |
| `visibilityScore`      | integer | 0-100 score for quick sorting and weekly trend dashboards.                                                                           |
| `sourceCount`          | integer | Number of unique extracted source domains.                                                                                           |
| `competitorCount`      | integer | Number of detected competitor mentions.                                                                                              |
| `engineStatus`         | string  | `ok_aio`, `ok_no_aio`, `partial_aio`, `blocked`, `timeout`, or `error`. |
| `error`                | string  | Short error message when rendering or parsing fails.                                                                                 |
| `blockMarkers`         | array   | Detected block/CAPTCHA phrases when Google blocks the session.                                                                       |
| `checkedAt`            | string  | UTC timestamp for the check.                                                                                                         |
| `runtimeSeconds`       | number  | Runtime for that prompt attempt.                                                                                                     |

### Use cases

- AI visibility tracking for target prompts
- GEO / AEO monitoring for target prompts
- AI Overview source tracking
- Brand visibility checks
- Domain citation checks
- Competitor visibility checks
- SEO source-gap research
- Weekly prompt monitoring for marketing teams

### Who should use it

This actor is useful when the question is not "what rank do I have in classic organic search?" but "does Google's AI answer show up, which brands are mentioned, and which external domains appear around that AI answer?"

Typical users:

- SEO teams tracking AI Overview exposure for commercial prompts
- content teams checking whether their domain appears near answer-style SERPs
- agencies monitoring client and competitor visibility across prompt lists
- SaaS teams watching category prompts such as "best CRM for small business"
- affiliate teams checking which publisher domains are surfaced for buyer-intent queries
- internal growth teams building weekly AEO/GEO dashboards

### Suggested monitoring workflow

1. Start with 5-20 high-intent prompts from Search Console, paid-search terms, sales calls, or competitor pages.
2. Run the actor with `maxConcurrency=1` and `timeoutSeconds=30`.
3. Export the dataset to Google Sheets, BigQuery, or a webhook.
4. Track these weekly fields: `aiOverviewAvailable`, `targetBrandMentioned`, `targetDomainCited`, `sourceDomains`, and `competitorMentions`.
5. Split prompts into buckets:
   - AIO exists and your brand/domain appears: maintain and monitor.
   - AIO exists but competitors appear: improve topical coverage and citation-worthy pages.
   - AIO exists but only publishers/tools appear: identify source-gap opportunities.
   - No AIO: monitor less often or test related prompt variants.

### Prompt list examples

For SaaS:

```json
{
  "prompts": [
    "best CRM software for startups",
    "best email marketing software for ecommerce",
    "best customer support software for SaaS"
  ],
  "brandName": "HubSpot",
  "domain": "hubspot.com",
  "competitors": ["Salesforce", "Zoho", "Pipedrive"],
  "country": "US",
  "language": "en",
  "maxPrompts": 3,
  "timeoutSeconds": 30,
  "maxConcurrency": 1
}
```

For local services:

```json
{
  "prompts": [
    "best emergency plumber in Austin",
    "best HVAC repair company in Austin",
    "how much does water heater repair cost in Austin"
  ],
  "brandName": "Example Plumbing",
  "domain": "exampleplumbing.com",
  "competitors": ["Roto-Rooter", "Mr. Rooter"],
  "country": "US",
  "language": "en",
  "maxPrompts": 3
}
```

For affiliate/content sites:

```json
{
  "prompts": [
    "best standing desk for home office",
    "best ergonomic chair for back pain",
    "best monitor light bar"
  ],
  "brandName": "Example Reviews",
  "domain": "examplereviews.com",
  "competitors": ["Wirecutter", "Tom's Guide", "PCMag"],
  "country": "US",
  "language": "en"
}
```

### Comparison with classic SERP rank tracking

| Need                                            | Classic rank tracker  | Google AI Overview Tracker      |
| ----------------------------------------------- | --------------------- | ------------------------------- |
| Track organic position                          | Yes                   | No                              |
| Detect whether AI Overview appears              | No                    | Yes                             |
| Extract answer text                             | No                    | Yes, when AIO is present        |
| Track brand mention in AI answer                | No                    | Yes                             |
| Track domains surfaced near AI answer           | Limited               | Yes                             |
| Monitor competitor mentions in generated answer | No                    | Yes                             |
| Best cadence                                    | Daily/weekly rankings | Weekly prompt visibility checks |

Use both when you need classic organic rankings and AI Overview visibility in the same reporting stack.

### API usage

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("tugelbay/google-ai-overview-tracker").call(run_input={
    "prompts": [
        "best answer engine optimization tools",
        "best AI visibility tracker",
        "how to optimize for Google AI Overviews",
        "best GEO tools for SaaS SEO",
        "AI search visibility software",
    ],
    "brandName": "Semrush",
    "domain": "semrush.com",
    "competitors": ["Ahrefs", "Surfer SEO", "Conductor"],
    "country": "US",
    "language": "en",
    "maxPrompts": 5,
    "timeoutSeconds": 30,
    "maxConcurrency": 1,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["prompt"], item["visibilityStatus"], item["visibilityScore"])
```

#### JavaScript

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

const client = new ApifyClient({ token: "YOUR_APIFY_TOKEN" });

const run = await client.actor("tugelbay/google-ai-overview-tracker").call({
  prompts: [
    "best answer engine optimization tools",
    "best AI visibility tracker",
    "how to optimize for Google AI Overviews",
    "best GEO tools for SaaS SEO",
    "AI search visibility software",
  ],
  brandName: "Semrush",
  domain: "semrush.com",
  competitors: ["Ahrefs", "Surfer SEO", "Conductor"],
  country: "US",
  language: "en",
  maxPrompts: 5,
  timeoutSeconds: 30,
  maxConcurrency: 1,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Webhook / scheduled monitoring

Create an Apify Task with your prompt list, then schedule it weekly. Use a webhook on run success to send the dataset to:

- Google Sheets
- BigQuery
- Slack
- Make/Zapier
- your internal dashboard

### Integrations

Plug this actor into your AI, automation, and workflow stack.

#### LangChain

```bash
pip install langchain-apify
export APIFY_API_TOKEN="your_token"
```

**As an agent tool:**

```python
from langchain_apify import ApifyActorsTool

tracker = ApifyActorsTool("tugelbay/google-ai-overview-tracker")
result = tracker.invoke({
    "run_input": {
        "prompts": ["best answer engine optimization tools", "AI visibility tracker"],
        "brandName": "Semrush",
        "domain": "semrush.com",
        "competitors": ["Ahrefs", "SE Ranking"],
        "country": "US",
        "maxPrompts": 2,
    }
})
## result: [{"prompt": "...", "aiOverviewAvailable": true, "answerText": "...", "targetBrandMentioned": true, ...}]
```

**As a RAG document loader:**

```python
from langchain_apify import ApifyWrapper
from langchain_core.documents import Document

apify = ApifyWrapper()
loader = apify.call_actor(
    actor_id="tugelbay/google-ai-overview-tracker",
    run_input={"prompts": ["how to optimize for Google AI Overviews"], "brandName": "My Brand"},
    dataset_mapping_function=lambda item: Document(
        page_content=item.get("answerText", ""),
        metadata={"prompt": item["prompt"], "visibility": item["visibilityStatus"], "sources": item["sourceDomains"]},
    ),
)
docs = loader.load()
```

#### n8n

1. Add the **Apify** community node (`@apify/n8n-nodes-apify`).
2. Choose operation **Run Actor**.
3. Authenticate with your Apify API token.
4. Actor: `tugelbay/google-ai-overview-tracker`.
5. Input JSON:
   ```json
   {
     "prompts": ["{{ $json.keyword }}"],
     "brandName": "My Brand",
     "domain": "mysite.com",
     "country": "US",
     "maxPrompts": 1
   }
   ```
6. Pipe output to Google Sheets, Airtable, Slack, or a webhook.

#### Make (Integromat)

1. Add the **Apify** app → **Run an Actor** module.
2. Connect your Apify API token.
3. Actor: `tugelbay/google-ai-overview-tracker`.
4. Map your keywords to `prompts`, set `brandName` and `domain`.
5. Route dataset items to any Make app (Slack, Microsoft 365, Notion, webhook, etc.).

#### Zapier

1. Create a Zap, add **Apify** action → **Run Actor**.
2. Choose `tugelbay/google-ai-overview-tracker`.
3. Map trigger data into `prompts`, `brandName`, `domain`.
4. Send results (`aiOverviewAvailable`, `targetBrandMentioned`, `visibilityStatus`, `answerText`) to any Zapier app (email, Airtable, CRM, Google Sheets, webhook).

#### MCP (Claude, ChatGPT, OpenAI Agents SDK)

Every Apify actor is exposed via the **Apify MCP server** at `https://mcp.apify.com` (Streamable HTTP). Any MCP-compatible client can discover and invoke `tugelbay/google-ai-overview-tracker` as a native tool.

```json
{
  "prompts": ["best AI visibility tools"],
  "brandName": "Your Brand",
  "domain": "yourdomain.com",
  "country": "US"
}
```

Agents receive structured output: `prompt`, `aiOverviewAvailable`, `answerText`, `targetBrandMentioned`, `targetDomainCited`, `visibilityStatus`, `visibilityScore`, `sourceDomains`, `competitorMentions`.

### Validation

Validation snapshot from 2026-04-25. This actor was built only after a 20-prompt stability probe:

- 20/20 clean headless Google SERP checks
- 19/20 prompts showed an AI Overview
- 1/20 prompts cleanly returned no AI Overview
- Median local probe runtime: 3.0 seconds. Apify runtime varies with proxy/session state.

Related validation file:

`docs/research/google-ai-overview-tracker-validation-results.md`

Official references rechecked on 2026-07-14:

- Google's [AI features and your website](https://developers.google.com/search/docs/appearance/ai-features) documentation explains that normal Search technical requirements and SEO fundamentals apply to AI features.
- Google's [Terms of Service](https://policies.google.com/terms) remain authoritative for use of Google surfaces; users must also respect rate limits, robots/access controls, and applicable client-reporting obligations.

The validation proves bounded extraction behavior, not stable AI Overview availability, ranking, traffic, or citation by another answer engine.

### Limitations

- Google decides whether AI Overview appears. Some queries, countries, or sessions may return no AI Overview.
- Google SERP layouts change. The actor returns `engineStatus` and `error` fields so monitoring jobs can detect layout or block changes.
- Perplexity always answers in English and ignores `country`/`language` — it has no equivalent regional-targeting parameters.
- Google uses the dedicated HTTP SERP service. Perplexity uses browser rendering.
- Keep concurrency low. The default is `1`, maximum is `3`.
- The default input checks 5 prompts so the first run produces a useful monitoring report. Reduce `maxPrompts` to `1` only for a tiny validation run.

### Pricing

Pay per event:

- `prompt-check` — **$0.01 per checked prompt** on the FREE plan as of 2026-07-14, with Store-plan discounts down to **$0.007**.
- Apify's standard synthetic Actor start event is currently **$0.00005**.

Use the public Pricing tab as the source of truth for the current plan-specific `prompt-check` rate. Actual platform cost also depends on Apify compute/runtime and your account plan. Keep prompt batches small until you know how often AIO appears for your niche.

### Troubleshooting

| Issue                                | Likely cause                                                      | What to do                                                                                |
| ------------------------------------ | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `aiOverviewAvailable=false`          | Google did not show an AI Overview for that query/session/country | This is a valid result. Try related prompts or another country/language.                  |
| `engineStatus=blocked`               | The source explicitly refused the request, or a Perplexity Cloudflare challenge did not clear after one new session | A hard refusal stops the affected batch and is not retried. A Perplexity challenge block is delivered and later prompts still run. |
| `engineStatus=timeout`               | SERP or AIO did not finish rendering within timeout               | Increase `timeoutSeconds` to 45-60 for harder prompts.                                    |
| `engineStatus=partial_aio` | Continuation or citation resolution is incomplete | Exclude this row from visibility-rate calculations; inspect completeness fields. |
| Competitor not detected              | Name spelling differs from input                                  | Add short brand variants to `competitors`, for example `Salesforce` and `Salesforce CRM`. |
| Target domain not cited              | Domain does not appear in extracted external source links         | Use `sourceDomains` to identify which domains are currently surfaced.                     |

### FAQ

#### Does this track ChatGPT, Gemini, Claude, Copilot, Grok, or Meta AI?

Not yet. This actor supports Google AI Overview and Perplexity via the `engine` input field. The remaining engines require separate validation because login, browser mode, rendering behavior, and source extraction differ.

#### Is `sourceLinks` exactly the same as AI Overview citations?

No. The Actor extracts links only from the supported AIO block and resolves recognized Google redirects. It reports unresolved destinations, but does not fetch the cited articles or prove that Google's response exposed every citation card. Check `citationLinksComplete` and `unresolvedCitationCount` on Google rows.

#### Why does the same prompt sometimes return different results?

Google personalizes and experiments with SERP layouts. Country, language, time, browser session, proxy, and Google's own AIO rollout can change whether an AI Overview appears.

#### Should I run this daily?

For most teams, weekly is enough. AI Overview visibility can move, but daily checks may add noise and cost before you have a stable prompt set.

#### Can I use this for client reporting?

Yes, if you explain the metric correctly: it tracks AI Overview availability, answer text, brand/domain visibility, and extracted external source domains for specific prompts at a specific time.

#### What is a good first prompt set?

Start with 10-20 prompts that already matter to the business: high-impression Search Console queries, paid search terms, "best X" category searches, sales objections, and competitor-comparison prompts.

### Data quality notes

- No-AIO is a valid output, not a failed run.
- For Google, calculate visibility rates only from `measurementComplete=true`; exclude `partial_aio`, `blocked`, `timeout`, and `error`.
- Use exact brand names and common short variants in `competitors`.
- Keep prompt wording stable over time if you want trend charts.
- Store raw datasets for repeatable historical reporting.

### Reporting template

For a weekly report, group the dataset by prompt and track these columns:

| Metric              | How to calculate                                                                   |
| ------------------- | ---------------------------------------------------------------------------------- |
| Visibility score    | Average `visibilityScore` across valid rows, or trend it by prompt week over week. |
| AIO coverage        | Count rows where `aiOverviewAvailable=true` divided by total valid rows.           |
| Brand visibility    | Count rows where `targetBrandMentioned=true` divided by rows with AIO.             |
| Domain visibility   | Count rows where `targetDomainCited=true` divided by rows with source domains.     |
| Competitor pressure | Count prompts where `competitorMentions` is not empty.                             |
| Source diversity    | Count unique `sourceDomains` across the prompt set.                                |
| Block/error rate    | Count `blocked`, `timeout`, and `error` statuses divided by total rows.            |

Keep the report honest by separating visibility changes from collection quality. A week with many `blocked` or `timeout` rows should be marked as a data-quality issue, not as a real visibility drop.

### Good prompt hygiene

- Use searcher language, not internal product jargon.
- Avoid changing prompt wording every week if you need trend lines.
- Include buying-intent prompts, comparison prompts, and problem-aware prompts.
- Keep country/language stable for each tracked prompt set.
- Do not mix unrelated markets in one dashboard; separate SaaS, local, ecommerce, and affiliate prompts.
- Add competitor aliases when brand names have common abbreviations.
- Review no-AIO prompts monthly and replace prompts that never trigger useful AI Overview data.

### Operational guardrails

Large prompt lists are supported, but small batches are easier to debug. A practical operating pattern is:

1. run the default 5-prompt starter monitor;
2. inspect `visibilityStatus`, `visibilityScore`, and `engineStatus` distribution;
3. expand to 25-50 prompts;
4. schedule weekly;
5. alert only on valid rows, not on blocked/error rows.

If you need hundreds of prompts, split them into multiple Tasks by category, country, or client. That keeps datasets easier to inspect. A hard source refusal can still stop later prompts in that run. A Perplexity Cloudflare challenge does not.

### Changelog

- **Unreleased** (2026-11-06) — Perplexity answer text is the visible main column (`innerText`), with script, style, noscript, and template excluded. An unbilled Perplexity row is `no_answer` with score 0 and `answer_not_rendered`, never `ok_aio`. Prices are unchanged.

- **Unreleased** (2026-11-06) — Perplexity does not treat sidebar, cookie, or `Working` chrome as an answer. A row without finished answer prose, or without a citation, is unresolved and is not charged. Prices and the `prompt-check` event name are unchanged.

- **Unreleased** (2026-11-06) — Perplexity waits out a Cloudflare managed challenge (HTTP 403 on a `__cf_chl` URL) in the residential browser, retries that prompt once on a new sticky session, and keeps going through the rest of the prompts. Hard refusals are unchanged. Output fields, the `prompt-check` event, and prices are unchanged.

- **2026-09-21** — Google uses the dedicated SERP service, restores supported inline answer continuations, excludes citation labels from brand matching, resolves source redirects, and flags incomplete observations. One Google search request per prompt; PPE event names and prices unchanged. Perplexity rendering is unchanged.

- **Unreleased** (2026-07-14) - reduces paid transient prompt attempts from three to two while preserving the free plan's single fresh-session retry. Attempt outcome logs record a run-local prompt index, tier, attempt number, status, retry decision, and usable-measurement recovery without logging the user's prompt; output fields, PPE events, pricing, and Store schemas are unchanged.

- **0.1.40** (2026-07-02) - added Perplexity as a second selectable `engine` alongside Google AI Overview, validated hands-on before implementation. Same output shape; Perplexity ignores `country`/`language` and always answers in English. Answer detection reads the `<main>` content area (falls back to full body) so nav/tab-bar chrome can't be mistaken for a rendered answer, and block detection now also catches Cloudflare challenge pages.

- **0.1.38** (2026-07-02) - prompt retries now trigger on any transient result (blocked, timeout, or error) with backoff between attempts, instead of only on "blocked" — timeouts and operational errors used to skip the retry path entirely.

- **0.1.28** (2026-05-16) - removed dated demand/CPC and fixed-price README claims, added the Konabayev guide reference, and kept runtime, input schema, and pricing behavior unchanged.

- **0.1.23** (2026-05-11) - switched the Store/input example to a 5-prompt paid monitoring pack and added dashboard-ready visibility status, score, source count, and competitor count fields.

- **0.1.10** (2026-04-26) - expanded README, clarified source-link semantics, and kept one-prompt first-run path.

- **0.1** (2026-04-26) - initial Google AI Overview-only MVP.

### Support & Feedback

If this actor saves you time, please **[leave a review](https://apify.com/tugelbay/google-ai-overview-tracker)** on its Store page — it takes under a minute and is the main trust signal that helps other users find a reliable tool.

Hit a bug or missing a feature? Open a ticket on the Actor's **Issues tab** — issues are typically answered within 24-48 hours and fixes ship fast.

### Related Actors

- [keyword-rank-tracker](https://apify.com/tugelbay/keyword-rank-tracker) — Track organic keyword positions separately from AI-answer visibility.
- [google-serp-checker](https://apify.com/tugelbay/google-serp-checker) — Check page indexation before investigating ranking or AI citations.

# Actor input Schema

## `engine` (type: `string`):

Google AI Overview uses the dedicated Apify Google SERP service with country/language below, without a Google login or third-party API key. Perplexity uses browser rendering and ignores country/language.

## `prompts` (type: `array`):

SEO, GEO, AEO or buyer-intent prompts. Google uses one SERP request per prompt and extracts the answer including supported deferred continuation. Inspect measurementComplete before using visibility metrics. The default is a small paid monitoring pack.

## `brandName` (type: `string`):

Brand to check for in the AI Overview answer text.

## `domain` (type: `string`):

Domain to check for in extracted source links.

## `competitors` (type: `array`):

Competitor names to detect in the AI Overview text.

## `country` (type: `string`):

Two-letter Google country code used as the gl parameter. Used only when engine is Google AI Overview.

## `language` (type: `string`):

Google interface language used as the hl parameter. Used only when engine is Google AI Overview.

## `maxPrompts` (type: `integer`):

Maximum prompts to process from the list. Default 5 creates a small monitoring report; use 10-50 for larger reports. The same prompt, timeout and retry limits apply on free and paid plans; there is no Actor monthly quota.

## `timeoutSeconds` (type: `integer`):

Google: deadline for the single SERP request, plus up to 15 seconds for citation redirects. Perplexity: browser navigation/answer wait timeout.

## `maxConcurrency` (type: `integer`):

Number of prompt checks in parallel. Keep at 1 to limit outstanding work when a source refuses requests.

## `proxyConfiguration` (type: `object`):

Applies only to Perplexity browser rendering. Google always uses the dedicated Apify GOOGLE_SERP HTTP service; this field does not alter Google routing. No Google account or separate provider API key is required.

## Actor input object example

```json
{
  "engine": "google_ai_overview",
  "prompts": [
    "best answer engine optimization tools",
    "best AI visibility tracker",
    "how to optimize for Google AI Overviews",
    "best GEO tools for SaaS SEO",
    "AI search visibility software"
  ],
  "brandName": "Semrush",
  "domain": "semrush.com",
  "competitors": [
    "Ahrefs",
    "Surfer SEO",
    "Conductor"
  ],
  "country": "US",
  "language": "en",
  "maxPrompts": 5,
  "timeoutSeconds": 30,
  "maxConcurrency": 1,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

AI Overview data: prompt, availability, brand/domain visibility, visibility score, competitor mentions, source links, engine status.

# 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 = {
    "engine": "google_ai_overview",
    "prompts": [
        "best answer engine optimization tools",
        "best AI visibility tracker",
        "how to optimize for Google AI Overviews",
        "best GEO tools for SaaS SEO",
        "AI search visibility software"
    ],
    "brandName": "Semrush",
    "domain": "semrush.com",
    "competitors": [
        "Ahrefs",
        "Surfer SEO",
        "Conductor"
    ],
    "country": "US",
    "language": "en",
    "maxPrompts": 5,
    "timeoutSeconds": 30,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tugelbay/google-ai-overview-tracker").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 = {
    "engine": "google_ai_overview",
    "prompts": [
        "best answer engine optimization tools",
        "best AI visibility tracker",
        "how to optimize for Google AI Overviews",
        "best GEO tools for SaaS SEO",
        "AI search visibility software",
    ],
    "brandName": "Semrush",
    "domain": "semrush.com",
    "competitors": [
        "Ahrefs",
        "Surfer SEO",
        "Conductor",
    ],
    "country": "US",
    "language": "en",
    "maxPrompts": 5,
    "timeoutSeconds": 30,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("tugelbay/google-ai-overview-tracker").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 '{
  "engine": "google_ai_overview",
  "prompts": [
    "best answer engine optimization tools",
    "best AI visibility tracker",
    "how to optimize for Google AI Overviews",
    "best GEO tools for SaaS SEO",
    "AI search visibility software"
  ],
  "brandName": "Semrush",
  "domain": "semrush.com",
  "competitors": [
    "Ahrefs",
    "Surfer SEO",
    "Conductor"
  ],
  "country": "US",
  "language": "en",
  "maxPrompts": 5,
  "timeoutSeconds": 30,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call tugelbay/google-ai-overview-tracker --silent --output-dataset

```

## MCP server setup

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

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/Hp0hXmEfEh31t5aOV/builds/OyNFOISdExWtc1EKV/openapi.json
