# AI Search Visibility Tracker (`lsso/ai-search-visibility-tracker`) Actor

See how often ChatGPT, Perplexity, Gemini and Claude mention, rank and cite your brand vs competitors. AI share of voice, 95% confidence intervals, prompt gaps, source opportunities, weekly trends and an HTML report. GEO made measurable.

- **URL**: https://apify.com/lsso/ai-search-visibility-tracker.md
- **Developed by:** [Haidong Nan](https://apify.com/lsso) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $15.00 / 1,000 ai answer analyzeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## 🔭 AI Search Visibility Tracker: does ChatGPT recommend your brand?

**Measure how often ChatGPT, Perplexity, Gemini and Claude mention, rank and cite your brand versus your competitors, with statistics you can trust.**

More and more buyers skip Google and ask AI: *"What's the best CRM for a small team?"* If the AI names three competitors and not you, you lose that customer and never find out. This Actor asks the AI engines the questions your buyers ask, as many times as you choose, and turns the answers into a **visibility score, share of voice, rankings, cited sources and a to-do list**.

- ✅ **Bring your own keys** (OpenAI, Perplexity, Gemini, Anthropic): you pay the AI vendors at cost, plus a small per-answer fee. Try it first with the **free demo**.
- ✅ 4 engines, all with **live web search**: ChatGPT · Perplexity · Gemini · Claude
- ✅ **95% confidence intervals**. AI answers change from run to run, so we sample each question several times and report an honest range instead of one lucky screenshot.
- ✅ Beautiful **HTML report**, plus JSON and a dataset of every answer
- ✅ **Weekly trend tracking** with Apify Schedules

***

### 🤔 What is AI search visibility (GEO)?

**Generative Engine Optimization (GEO)**, also called AEO or LLM SEO, is the practice of getting your brand recommended in AI-generated answers. Traditional SEO tools cannot see inside ChatGPT. This Actor measures it directly:

| Metric | What it tells you |
|---|---|
| **Visibility score (0–100)** | One number to track over time, overall and per AI engine |
| **Mention rate ± 95% CI** | How often you appear in answers, with a statistical range |
| **Share of voice** | Your share of all brand mentions, compared with competitors |
| **Rank / recommended first** | Whether you are listed first, third, or not at all |
| **Citation rate** | How often the AI cites **your own website** as a source |
| **Prompt gaps** | The exact questions where competitors appear but you don't |
| **Source opportunities** | The review sites and blogs AI cites when it recommends competitors, so you know where to get listed |
| **Untracked competitors** | Brands the AI keeps recommending that you didn't list |
| **Sentiment** | The tone of the text around each mention |

### 🚀 Quick start (2 minutes)

1. Enter **your brand**, for example `Notion | notion.com`.
2. Add **competitors**, one per line.
3. Enter your **category**, for example `project management software`. We generate realistic buyer questions for you in English, Chinese, Korean or Japanese.
4. Paste the API keys of the engines you want to measure.
5. Click **Start**, then open the **HTML report** in the Output tab.

> 💡 Just want to see the output? Run it with no keys. You get a **free demo report** built on fictional brands.

### ⬇️ Input example

```json
{
  "brand": "Notion | notion.com | Notion AI",
  "competitors": ["ClickUp | clickup.com", "Asana | asana.com", "Monday.com | monday.com | monday"],
  "category": "project management software",
  "useCases": ["remote teams", "startups"],
  "engines": ["chatgpt", "perplexity", "gemini"],
  "samplesPerPrompt": 3,
  "country": "United States",
  "projectName": "notion-weekly"
}
```

### ⬆️ Output

- **HTML report** (key-value store → `REPORT`): KPI cards, recommendations, leaderboard, per-engine heatmap, prompt gaps, source opportunities
- **Summary JSON** (`OUTPUT`): all metrics, ready for dashboards and APIs
- **Dataset**: one row per AI answer, containing engine, prompt, whether you were mentioned, rank, whether you were cited, sentiment, every brand in order, cited domains, full answer text and the search queries the AI ran

Example dataset row:

```json
{
  "engine": "Perplexity", "prompt": "What are the best project management software options right now?",
  "brandMentioned": true, "brandRank": 2, "brandCited": true, "brandSentiment": 0.5,
  "brandsMentioned": ["ClickUp", "Notion", "Asana"],
  "citedDomains": ["zapier.com", "notion.com", "g2.com"]
}
```

### 💵 How much does it cost?

You pay only for answers that were successfully analysed. Failed calls and demo runs are free.

| Mode | Price per AI answer | 100 answers | Who pays the AI vendor |
|---|---|---|---|
| **Bring your own keys** | **$0.015** | $1.50 | You, at the vendor's cost price |

A typical weekly check of 8 questions × 3 engines × 2 samples = 48 answers costs **$0.72** plus the AI vendors' own costs on your keys. Use *Max answers per run* to cap your spend.

### 🎯 Who is it for?

- **Marketing and SEO teams** tracking brand presence in AI search
- **Agencies** producing monthly GEO reports for clients (schedule it and share the HTML report)
- **Founders** checking whether AI recommends their product or a competitor's
- **PR and content teams** deciding which publications to target, based on source opportunities

### 🔁 Track trends weekly

Give your runs a `projectName` and create an **Apify Schedule**, for example every Monday. Each report then shows how every metric changed since the last run, plus **new gaps** and **closed gaps**. Connect the dataset to Google Sheets, Slack, Looker Studio or Make through Apify integrations.

### 🧠 How it works

1. Each question is sent to each engine through its **official API with web search turned on**: the OpenAI Responses API with web search, Perplexity Sonar, Gemini with Google Search grounding, and Claude with web search.
2. Each answer is scanned for brand names and aliases. Word boundaries prevent false matches, so "Monday" does not match "Mondays". The scan also records list positions, cited URLs and sentiment.
3. Results are aggregated into the metrics. The **visibility score** is `100 × (0.5·mention rate + 0.3·avg(1/rank) + 0.2·citation rate)`.

### 🤖 Use it from AI agents (MCP): Claude, Cursor & any MCP client

This Actor works as a ready-made **connector for AI assistants**. Add one URL and your agent can call it on its own:

```
https://mcp.apify.com?tools=lsso/ai-search-visibility-tracker
```

- **Claude** (claude.ai / Claude Desktop): *Settings → Connectors → Add custom connector*, paste the URL above, sign in to Apify.
- **Cursor / VS Code / any MCP client**: add it to your MCP config:

```json
{ "mcpServers": { "ai-visibility": { "url": "https://mcp.apify.com?tools=lsso/ai-search-visibility-tracker" } } }
```

- **Claude Code**: `claude mcp add --transport http ai-visibility "https://mcp.apify.com?tools=lsso/ai-search-visibility-tracker"`

Sign-in uses Apify OAuth in the browser, so you never paste a token into the config. Then just ask:

> *"Does ChatGPT recommend my brand (Acme CRM) when people ask for the best CRM for small teams? Compare with HubSpot and Pipedrive."*

> *"Which websites do Perplexity and Gemini cite when they answer questions about project management tools?"*

> *"Give me a to-do list to get my product mentioned more often in AI answers."*

Results include a visibility score, share of voice and a prioritized to-do list, ready for the agent to explain. You pay only for results, same as a normal run.

### ❓ FAQ

**Is this the same as what I see in the ChatGPT app?**
It is very close. The Actor uses the vendors' official APIs with live search, which is the same retrieval technology. The consumer apps may add personalisation or memory, so treat the results as a repeatable, market-level measurement.

**Why sample each question several times?**
AI answers are non-deterministic. One run can show you at #1 and the next can leave you out entirely. Sampling gives a real rate with a confidence interval.

**Is it legal? Does it scrape anything?**
Nothing is scraped. All data comes from the vendors' official APIs. No logins are used and no personal data is collected.

**Can I use my own API keys?**
Yes. Keys are stored as secret inputs, used only for your run, and never written to the results. BYOK runs are billed at the lower rate.

**Which languages are supported?**
Questions can be generated in English, Chinese, Korean and Japanese, and you can write custom questions in any language. You can also set the answer language and market with `language` and `country`.

**Can I use it from an AI agent, n8n or Make?**
Yes. Call it through the Apify API or the Apify MCP server, and read `OUTPUT` for machine-readable results.

### 📝 Changelog

- **1.2** (2026-09-24): Built-in access removed; the Actor now always runs on your own keys (or the free demo), so the per-answer fee stays low and predictable.
- **1.1**: Built-in AI access (no keys needed). Automatic fallback when a free Gemini key has no search quota. Smarter retries on rate limits.
- **1.0**: First release: 4 engines, confidence intervals, source opportunities, trend tracking, HTML report.

# Actor input Schema

## `brand` (type: `string`):

Format: <code>Name | domain.com | alias1; alias2</code>. Domain and aliases are optional but recommended (domain enables citation tracking).

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

One per line, same format as your brand: <code>Name | domain.com | aliases</code>.

## `category` (type: `string`):

What you sell, e.g. "project management software", "running shoes", "CRM for real estate". Used to generate the questions real buyers ask AI assistants.

## `useCases` (type: `array`):

Adds prompts like "best {category} for {use case}".

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

Your own questions to ask every AI engine. Combined with the generated ones.

## `generatePrompts` (type: `boolean`):

Generate realistic buyer-intent questions from the category (recommended).

## `maxGeneratedPrompts` (type: `integer`):

How many auto-generated prompts to use.

## `includeBrandedPrompts` (type: `boolean`):

Adds questions that name your brand directly. Off by default because unbranded questions measure organic visibility.

## `engines` (type: `array`):

Engines to query. Each needs your own API key below. Without keys, the Actor runs a free demo on fictional data.

## `openaiApiKey` (type: `string`):

platform.openai.com → API keys. Used only for this run, never stored in results.

## `perplexityApiKey` (type: `string`):

perplexity.ai → Settings → API. Used only for this run.

## `geminiApiKey` (type: `string`):

aistudio.google.com → Get API key.

## `anthropicApiKey` (type: `string`):

console.anthropic.com → API keys. Used only for this run.

## `samplesPerPrompt` (type: `integer`):

AI answers vary between runs. More samples = tighter confidence intervals (reported as a Wilson 95% interval).

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

e.g. United States, South Korea, Germany. Localises the answers.

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

e.g. English, Korean, Chinese, Japanese. Also switches the generated prompts to that language (en/zh/ko/ja).

## `projectName` (type: `string`):

Runs with the same project name are compared to show changes over time. Schedule the Actor weekly to track trends.

## `maxAnswers` (type: `integer`):

Hard cap on AI answers per run (cost control).

## `concurrencyPerEngine` (type: `integer`):

Parallel requests to each AI engine. Lower it if you hit rate limits.

## `openaiModel` (type: `string`):

Default: gpt-6-luna

## `perplexityModel` (type: `string`):

Default: sonar (sonar-pro for deeper answers)

## `geminiModel` (type: `string`):

Default: gemini-3.5-flash

## `anthropicModel` (type: `string`):

Default: claude-haiku-4-5-20251001

## Actor input object example

```json
{
  "brand": "Notion | notion.com | Notion AI",
  "competitors": [
    "ClickUp | clickup.com",
    "Asana | asana.com",
    "Monday.com | monday.com | monday",
    "Trello | trello.com"
  ],
  "category": "project management software",
  "useCases": [
    "remote teams"
  ],
  "generatePrompts": true,
  "maxGeneratedPrompts": 8,
  "includeBrandedPrompts": false,
  "engines": [
    "chatgpt",
    "perplexity",
    "gemini",
    "claude"
  ],
  "samplesPerPrompt": 2,
  "maxAnswers": 300,
  "concurrencyPerEngine": 3
}
```

# Actor output Schema

## `report` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `answers` (type: `string`):

No description

# 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 = {
    "brand": "Notion | notion.com | Notion AI",
    "competitors": [
        "ClickUp | clickup.com",
        "Asana | asana.com",
        "Monday.com | monday.com | monday",
        "Trello | trello.com"
    ],
    "category": "project management software",
    "useCases": [
        "remote teams"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lsso/ai-search-visibility-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 = {
    "brand": "Notion | notion.com | Notion AI",
    "competitors": [
        "ClickUp | clickup.com",
        "Asana | asana.com",
        "Monday.com | monday.com | monday",
        "Trello | trello.com",
    ],
    "category": "project management software",
    "useCases": ["remote teams"],
}

# Run the Actor and wait for it to finish
run = client.actor("lsso/ai-search-visibility-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 '{
  "brand": "Notion | notion.com | Notion AI",
  "competitors": [
    "ClickUp | clickup.com",
    "Asana | asana.com",
    "Monday.com | monday.com | monday",
    "Trello | trello.com"
  ],
  "category": "project management software",
  "useCases": [
    "remote teams"
  ]
}' |
apify call lsso/ai-search-visibility-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lsso/ai-search-visibility-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/4BghPbQW1yDhIVUTH/builds/u41PfiimdC0g4rmrb/openapi.json
