# AI Search Visibility Audit: ChatGPT & Perplexity (`kyungminlee/ai-search-visibility-audit`) Actor

Measure how often ChatGPT, Perplexity and Gemini recommend your brand: the Actor reads your site, writes 30 buyer-intent questions and samples each engine several times. HTML report with mention and citation rates (95% CI), competitor share of voice, cited sources and every sentence about you.

- **URL**: https://apify.com/kyungminlee/ai-search-visibility-audit.md
- **Developed by:** [Kyungmin Lee](https://apify.com/kyungminlee) (community)
- **Categories:** Marketing, SEO tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2,100.00 / 1,000 audit reports

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?

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

## AI Search Visibility Audit: ChatGPT & Perplexity

Find out **how often AI answer engines recommend your brand** when buyers ask
them for advice — and who they recommend instead. The Actor reads your website,
writes 30 realistic buyer-intent questions, asks ChatGPT, Perplexity and/or
Gemini each of them several times, and delivers a shareable **HTML report**
with your brand's mention rate, citation rate, share of voice against
competitors, the sources the engines rely on, and every sentence they wrote
about you. This is an unofficial tool and is not affiliated with OpenAI,
Perplexity, or Google.

### What does the audit measure?

- **Mention rate** – share of AI answers that name your brand (or an alias or
  your domain), with a 95% confidence interval.
- **Citation rate** – share of answers whose sources include your website.
- **Average position** – where your brand appears among the brands named.
- **Share of voice** – your mentions versus each listed competitor.
- **Most cited sources** – the domains AI engines trust for your market (the
  places where you need to be present).
- **What the engines say** – every sentence about your brand, so you can catch
  outdated or wrong claims.
- **By engine and by question type** – best-of lists, comparisons, how-to,
  pricing, trust, and use-case questions are reported separately.

### How it works

1. **Crawl** – the homepage plus up to five key pages (about, products,
   pricing, blog) are read to understand what you sell and to whom.
2. **Prompt generation** – an LLM (OpenAI if a key is given, otherwise Gemini)
   turns that profile into buyer-intent questions
   spread across six categories. Questions do not name your brand except in
   comparison / trust categories, so results reflect unprompted recall.
3. **Sampling** – every question is asked `samplesPerPrompt` times per engine
   (default 3), because AI answers vary from run to run. ChatGPT is queried
   through the OpenAI Responses API with web search when available, Perplexity
   through `sonar`, Gemini with Google Search grounding.
4. **Analysis** – mentions, citations, ranks, competitor mentions and cited
   domains are extracted from every answer; rates get Wilson 95% intervals.
5. **Report** – `REPORT.html` in the run's key-value store, plus one `audit`
   summary item and one `promptResult` item per answer in the dataset.

### How to use it

1. Enter your **Website URL** and **Brand name**; add **Competitors** to
   measure share of voice.
2. Paste at least one API key. **Cheapest option: a free Google AI Studio
   key** — select the Gemini engine and the audit runs on Gemini's free tier
   (questions are generated by Gemini too). The free tier is small (observed
   September 2026: 20 requests per day per model, no Google Search grounding),
   so set about 12 prompts × 1 sample for a free key; a paid Gemini key or an
   OpenAI key handles the default 30 × 3. Add a Perplexity key for Perplexity.
3. Keep 30 prompts × 3 samples for a first audit (about 90 answers per engine;
   typically under $1 of OpenAI usage with `gpt-4o-mini`, a few cents on a
   paid Gemini key). Rate limits are waited out automatically; when a provider
   quota runs out mid-audit the engine stops early and the report says so.
4. Click **Start**. Open `REPORT.html` from the **Storage → Key-value store**
   tab or via the link in the `audit` dataset item.

No API key? Enable **Mock mode** to see the full report format with simulated
answers — mock runs are free and clearly labelled.

### Input

| Field | Default | Notes |
|---|---|---|
| `websiteUrl` | – | Brand homepage (required). |
| `brandName` | – | Brand as written in text (required). |
| `brandAliases` | – | Extra spellings or product names counted as mentions. |
| `competitors` | – | Up to 10 competitor names. |
| `businessDescription` | – | Optional context to improve prompt generation. |
| `promptCount` | 30 | 5–60 generated questions. |
| `samplesPerPrompt` | 3 | 1–5 answers per question per engine. |
| `engines` | `["openai"]` | `openai`, `perplexity`, `gemini`. |
| `openaiApiKey` / `openaiModel` | – / `gpt-4o-mini` | ChatGPT engine; generates the questions when present. |
| `geminiApiKey` / `geminiModel` | – / `gemini-2.5-flash` | Gemini engine (Google Search grounding when the key has grounding quota); generates the questions when there is no OpenAI key. If the model is retired or has no quota, the newest available Flash model is used. |
| `perplexityApiKey` | – | Perplexity `sonar` engine. |
| `mockMode` | `false` | Simulated answers, free of charge. |

### Output

`audit` item (one per run):

```json
{
  "type": "audit",
  "brand": "Apify",
  "engines": ["openai", "perplexity"],
  "promptCount": 30,
  "brandMentionRate": {"count": 49, "n": 180, "rate": 0.2722, "ci95": [0.2115, 0.3426]},
  "brandCitationRate": {"count": 31, "n": 180, "rate": 0.1722, "ci95": [0.1236, 0.2348]},
  "averageBrandRank": 1.6,
  "shareOfVoice": {"Apify": {"mentions": 49, "share": 0.31}, "Bright Data": {"mentions": 44, "share": 0.28}},
  "topCitedDomains": [{"domain": "g2.com", "count": 38}, {"domain": "apify.com", "count": 31}],
  "reportUrl": "https://api.apify.com/v2/key-value-stores/.../records/REPORT.html"
}
```

`promptResult` items (one per answer): `engine`, `model`, `promptId`,
`category`, `prompt`, `sampleIndex`, `answer`, `citations`, `brandMentioned`,
`brandCited`, `brandRank`, `competitorsMentioned`, `citedDomains`,
`brandSentences`, `error`, `latencyMs`, `mode`.

### Pricing

One `audit` event per completed live audit (the report and dataset are
delivered first; a run that fails before the report is written is not
charged, and a partial audit in which fewer than half of the planned answers
succeeded — for example because a free-tier quota ran out — is delivered free).
Mock runs are free. Your own OpenAI / Perplexity / Gemini API usage is billed by
those providers separately: typically well under $1 per audit on OpenAI with
the default settings, cents on a paid Gemini key, nothing on Gemini's free tier.

### Tips

- Run the audit monthly and compare `brandMentionRate` over time; the
  confidence interval tells you whether a change is real.
- Look at **Most cited sources** first: getting listed on those domains is the
  fastest way to raise your citation rate.
- Use `businessDescription` when your homepage is thin or JavaScript-only.
- Keep prompts at 30 and samples at 3 for comparable results across runs.

### FAQ

**Do I need to give you my API keys?** Keys are entered as secret input
fields, used only during the run, and never stored in the dataset or report.

**Why do the numbers differ between runs?** AI answers are non-deterministic;
that is exactly why each prompt is sampled several times and rates carry
confidence intervals. Larger samples narrow the interval.

**Which models are used?** OpenAI `gpt-4o-mini` by default (configurable),
Perplexity `sonar`, Gemini `gemini-2.5-flash` (configurable) with Google Search
grounding.

**Can I run it without paying for an AI API?** Yes, on a small scale: a Google AI
Studio key has a free tier (observed September 2026: 20 requests per day per
model, without Google Search grounding). Select only the Gemini engine, set
about 12 prompts × 1 sample, and leave the other keys empty. Larger audits need a
paid Gemini or OpenAI key.

**Can it fix my visibility?** It measures and points to the sources that
matter; content and PR work is up to you.

# Actor input Schema

## `websiteUrl` (type: `string`):

Homepage of the brand to audit. The Actor reads the homepage and up to five key pages (about, products, pricing, blog) to understand what the brand sells.

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

How the brand is written in text, for example 'Apify'. Mentions are matched case-insensitively together with the website domain.

## `brandAliases` (type: `array`):

Other spellings or product names that count as a brand mention (optional).

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

Competitor brand names to measure share of voice against (0-10).

## `businessDescription` (type: `string`):

Optional one-paragraph description of what the brand offers and who buys it. Improves prompt generation; leave empty to rely on the crawled site.

## `promptCount` (type: `integer`):

How many buyer-intent questions to generate and test (5-60). With a free Gemini key use 10-15.

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

How many times each prompt is asked per engine. AI answers vary, so 3 samples give a more stable citation rate. With a free Gemini key use 1.

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

Which answer engines to sample. Each engine needs its own API key below; engines without a key are skipped (or mocked when Mock mode is on). Cheapest live setup: Gemini only with a free Google AI Studio key and a small audit (about 15 answers per day).

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

Enables the ChatGPT engine (Responses API with web search when available, chat completions otherwise) and, when present, generates the questions. Optional: with only a Gemini key, Gemini generates the questions. Get one at platform.openai.com. Typical cost per audit with defaults: under $1.

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

OpenAI model for prompt generation and the ChatGPT engine.

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

Enables the Perplexity engine (model 'sonar'), which returns web citations. Get one at perplexity.ai/settings/api.

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

Enables the Gemini engine (Google Search grounding when your key has grounding quota) and generates the questions when no OpenAI key is given. A free Google AI Studio key works but is small (observed Sept 2026: 20 requests per day per model, no grounding): keep Number of prompts x Samples per prompt at or below about 15 for a free key, or use a paid Gemini key for the default 30 x 3. Rate limits are waited out and the Actor switches to another Flash model when one is exhausted.

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

Gemini model for the Gemini engine and (without an OpenAI key) prompt generation. Falls back to gemini-2.0-flash / gemini-flash-latest if the model is not available.

## `mockMode` (type: `boolean`):

Generate a demo report with simulated answers instead of calling any AI API. Automatically used when no API key is provided. Mock audits are not charged.

## Actor input object example

```json
{
  "websiteUrl": "https://apify.com",
  "brandName": "Apify",
  "brandAliases": [],
  "competitors": [
    "Bright Data",
    "Zyte",
    "ScrapingBee"
  ],
  "promptCount": 30,
  "samplesPerPrompt": 3,
  "engines": [
    "openai"
  ],
  "openaiModel": "gpt-4o-mini",
  "geminiModel": "gemini-2.5-flash",
  "mockMode": false
}
```

# Actor output Schema

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

No description

## `results` (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 = {
    "websiteUrl": "https://apify.com",
    "brandName": "Apify",
    "brandAliases": [],
    "competitors": [
        "Bright Data",
        "Zyte",
        "ScrapingBee"
    ],
    "businessDescription": "",
    "promptCount": 30,
    "samplesPerPrompt": 3,
    "engines": [
        "openai"
    ],
    "openaiModel": "gpt-4o-mini",
    "geminiModel": "gemini-2.5-flash",
    "mockMode": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("kyungminlee/ai-search-visibility-audit").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 = {
    "websiteUrl": "https://apify.com",
    "brandName": "Apify",
    "brandAliases": [],
    "competitors": [
        "Bright Data",
        "Zyte",
        "ScrapingBee",
    ],
    "businessDescription": "",
    "promptCount": 30,
    "samplesPerPrompt": 3,
    "engines": ["openai"],
    "openaiModel": "gpt-4o-mini",
    "geminiModel": "gemini-2.5-flash",
    "mockMode": False,
}

# Run the Actor and wait for it to finish
run = client.actor("kyungminlee/ai-search-visibility-audit").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 '{
  "websiteUrl": "https://apify.com",
  "brandName": "Apify",
  "brandAliases": [],
  "competitors": [
    "Bright Data",
    "Zyte",
    "ScrapingBee"
  ],
  "businessDescription": "",
  "promptCount": 30,
  "samplesPerPrompt": 3,
  "engines": [
    "openai"
  ],
  "openaiModel": "gpt-4o-mini",
  "geminiModel": "gemini-2.5-flash",
  "mockMode": false
}' |
apify call kyungminlee/ai-search-visibility-audit --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kyungminlee/ai-search-visibility-audit"
        }
    }
}
```

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/vKKmIzSKwyrh6KvUB/builds/EeWFnGJgRLrH7m2rn/openapi.json
