# AI Visibility Monitor: ChatGPT, Perplexity & Gemini (`matidepa22/ai-visibility-monitor`) Actor

Check whether AI search engines recommend your brand. Get mention rate, ranking position, share of voice vs competitors and the sources AI cites.

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

## Pricing

from $50.00 / 1,000 ai answer checkeds

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 Visibility Monitor — Is ChatGPT recommending your brand?

More and more buyers ask **ChatGPT, Perplexity and Gemini** instead of Google. This Actor asks those AI engines the questions your customers ask and tells you:

- **Appearance rate** — in what % of answers your brand appears, measured over repeated runs of each question
- **Position when mentioned** — how high you tend to be listed when AI does recommend you
- **Share of voice vs competitors** — who AI recommends instead of you
- **Cited sources** — which websites AI trusts for your category, and whether your own site is one of them
- **Sentiment** — whether each answer describes you positively, neutrally or negatively
- **Your cited pages** — which URLs on your site AI engines use as sources
- **Gaps** — the exact prompts where competitors show up and you don't

Use it for **GEO / AEO** (generative engine optimization), AI brand monitoring, agency client reports, or competitor research.

### Why check more than one engine?

Each AI engine searches the web differently, so they often disagree. In a test run (September 2026) we asked all three *"¿Cuál es la mejor billetera virtual en Argentina?"* (best digital wallet in Argentina), tracking Mercado Pago against Ualá and Naranja X:

| Engine | Mercado Pago ranked | Sources it relied on |
|---|---|---|
| ChatGPT | **1st** | mercadopago.com.ar, uala.com.ar |
| Perplexity | **1st** | clarin.com, cronista.com, perfil.com… |
| Gemini | **3rd** — behind Ualá and Naranja X | infobae.com, lavoz.com.ar, cronista.com… |

Checking only ChatGPT would have missed that Gemini recommends two competitors first — and the cited sources show which publications to target to change that.

### How to use

1. Enter your **brand** and a few **competitors**.
2. Either describe your market in **topic** (e.g. *"CRM for small agencies"*) and the Actor writes realistic buyer questions for you, or add your own **prompts** like *"alternatives to HubSpot"*. Any language works.
3. Pick the engines and run. **Schedule it weekly** to track changes over time.

Each prompt is sent to each selected engine with live web search enabled, so results reflect what users see today.

#### Why repeated runs

Ask ChatGPT the same question twice and you'll often get a different list of brands. A single answer (and the rank inside it) is mostly noise. That's why the Actor asks every prompt several times per engine (`runsPerPrompt`, default 3) and reports **the share of runs where you appear**, per prompt and per engine. Use 5–10 runs for decisions that matter.

#### Example input

```json
{
  "brand": "Pipedrive",
  "brandDomains": ["pipedrive.com"],
  "competitors": ["HubSpot", "Salesforce", "Zoho"],
  "topic": "CRM for small sales teams",
  "promptCount": 10,
  "prompts": ["HubSpot alternatives for agencies"],
  "engines": ["openai", "perplexity", "gemini"],
  "country": "US"
}
```

Generated prompts never include your brand name, so a mention is always earned. Generating prompts, sentiment analysis and the report are free; you only pay per answer checked.

### Output

**Dataset** — one row per prompt × engine:

```json
{
  "prompt": "What is the best CRM for a small sales team?",
  "engine": "openai",
  "brandMentioned": true,
  "brandPosition": 2,
  "brandDomainCited": true,
  "brandContext": "…HubSpot first, then Pipedrive, which is simpler for small sales teams…",
  "brandSentiment": "positive",
  "competitors": [{ "name": "HubSpot", "mentioned": true, "position": 1, "count": 2 }],
  "citedDomains": ["g2.com", "pipedrive.com"],
  "answer": "full AI answer…",
  "error": null
}
```

**`SUMMARY` record** (Key-value store) — the scorecard, overall and per engine, plus `byPrompt` (appearance rate for every prompt × engine across runs), sentiment counts and `brandCitedPages` (your URLs that AI engines cited):

```json
{
  "brand": "Pipedrive",
  "overall": {
    "checks": 9,
    "brandMentionRate": 0.667,
    "brandAvgPosition": 1.5,
    "brandTop1Rate": 0.444,
    "brandDomainCitedRate": 0.333,
    "entities": [
      { "name": "HubSpot", "mentions": 8, "shareOfVoice": 0.4, "avgPosition": 1.2 },
      { "name": "Pipedrive", "isBrand": true, "mentions": 6, "shareOfVoice": 0.3, "avgPosition": 1.5 }
    ],
    "topCitedDomains": [{ "domain": "g2.com", "count": 5 }]
  },
  "byEngine": { "openai": { "…": "same fields" }, "gemini": {}, "perplexity": {} },
  "promptsWithoutBrand": [
    { "prompt": "HubSpot alternatives for agencies", "engine": "gemini", "competitorsMentioned": ["Zoho"] }
  ]
}
```

Download the dataset as JSON, CSV or Excel from the run page, or read the summary via API:
`https://api.apify.com/v2/actor-runs/{RUN_ID}/key-value-store/records/SUMMARY`

### Client-ready report

Every run also saves a formatted **HTML report** (`REPORT` in the key-value store, linked in the Output tab): a written summary with recommendations, appearance by engine, share of voice, a prompt-by-prompt table across runs, sentiment, and the sources AI engines cite. It's in English or Spanish (auto-detected from `country`), and agencies can add their name with `agencyName` to send it as their own. Open it and print to PDF.

### Pricing

Pay only for answers checked — **one check = one prompt on one engine**. Failed requests are never charged.

| | Price per check |
|---|---|
| Using our API keys (default) | **$0.05** |
| Using your own OpenAI / Perplexity / Gemini keys | **$0.01** |

One check = one answer from one engine. Examples with our keys:

- 10 prompts × 3 engines × 1 run = 30 checks = **$1.50**
- 10 prompts × 3 engines × 3 runs (default) = 90 checks = **$4.50**
- Weekly tracking of 10 prompts × 3 engines × 3 runs ≈ **$18 / month**

You can set a maximum cost per run; the Actor stops before exceeding it.

### Integrations

- **Schedules** — run weekly or daily from Apify Schedules to build a visibility trend.
- **API** — start runs and fetch results from any language with the Apify API.
- **AI agents** — call it from Claude, Cursor or any MCP client through the Apify MCP server.
- **n8n, Make, Zapier** — use the Apify integration to send results to Google Sheets, Slack or your client reports.
- **Ready-made n8n workflow** — [AI Visibility Weekly Report template](https://matidepa.gumroad.com/l/ai-visibility-n8n): runs this Actor every Monday, logs results to Google Sheets and posts a summary to Slack. 5-minute setup.

### Tips

- Write prompts the way customers speak, and **don't include your brand name** in them — otherwise you'll always be "mentioned".
- 10–20 prompts × 3 engines × 3 runs gives a stable picture. Weekly schedules show the trend over time.
- Name variants matter: AI may say "Seguros Rivadavia" instead of "Rivadavia Seguros". The Actor auto-detects common variants (`autoAliases`), and you can add your own with `brandAliases` or `Competitor | variant` in the competitors list. The variants used are listed in `SUMMARY.aliasesUsed`.
- Positions are ranked among the brands you list (your brand + competitors). If AI recommends a brand you didn't list, it won't count — read `answer` on a few rows to spot competitors you're missing.
- Use **country** (e.g. `US`, `AR`, `ES`) to localize web search where the engine supports it.

### FAQ

**Which models are used?** OpenAI Responses API with web search, Perplexity Agent API with web search, and Gemini with Google Search grounding. You can override models in the Advanced section.

**Does it scrape chatgpt.com?** No. It uses the official APIs, so it's stable and within each provider's terms. API answers can differ slightly from the consumer apps, which may add personalization.

**Are my API keys safe?** Keys you provide are stored as secret inputs and are only sent to the provider they belong to.

**Why did an engine get skipped?** If an API key is invalid or out of credits, that engine is disabled for the rest of the run and the remaining engines continue. The reason is in the `error` field.

# Actor input Schema

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

The brand, product or company to track.

## `topic` (type: `string`):

Describe your market, e.g. "CRM for small agencies" or "billeteras virtuales en Argentina". The Actor writes realistic buyer questions for you (free). Leave empty to use only your own prompts.

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

How many questions to generate from the topic. Each one is sent to every selected engine.

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

Your own questions (optional if you set a topic). Each prompt is sent to every selected engine.

## `runsPerPrompt` (type: `integer`):

How many times each prompt is asked to each engine. AI answers change a lot between identical requests, so the share of runs where you appear is far more reliable than a single answer. 3–5 is a good balance; each run is one billed check.

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

Competitor names to compare against. Add other names AI may use after a | sign, e.g. "Rivadavia Seguros | Seguros Rivadavia".

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

Other spellings or product names that count as a mention of your brand.

## `autoAliases` (type: `boolean`):

Add common unambiguous variants for your brand and competitors (e.g. "UTDT" for Universidad Torcuato Di Tella), so mentions under another name aren't missed. Free; the list used is saved in the summary.

## `brandDomains` (type: `array`):

Your websites (e.g. notion.so). Used to detect when AI cites you as a source.

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

Which AI search engines to query.

## `analyzeSentiment` (type: `boolean`):

Classify each mention as positive, neutral or negative (free, uses OpenAI).

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

Two-letter country code to localize web search, e.g. US, AR, ES. Not supported by every engine.

## `generateReport` (type: `boolean`):

Save a formatted HTML report (summary, recommendations, prompt-by-prompt table, sources) as REPORT in the key-value store. Print it to PDF from your browser to send to clients.

## `reportLanguage` (type: `string`):

Language of the report and its written summary.

## `agencyName` (type: `string`):

Optional. Shown as "Prepared by <name>" at the top of the report, so agencies can send it to clients as their own.

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

How many AI requests run in parallel.

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

Bring your own key for a lower price per check. Leave empty to use ours.

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

Bring your own key for a lower price per check. Leave empty to use ours.

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

Bring your own key for a lower price per check. Leave empty to use ours.

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

Override the OpenAI model used for web search.

## `perplexityPreset` (type: `string`):

Perplexity Agent API preset (fast, low, medium, high).

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

Override the Gemini model used for Google Search grounding.

## Actor input object example

```json
{
  "brand": "Notion",
  "topic": "note-taking apps for teams",
  "promptCount": 10,
  "runsPerPrompt": 3,
  "competitors": [
    "Evernote",
    "Obsidian",
    "Coda"
  ],
  "autoAliases": true,
  "brandDomains": [
    "notion.so",
    "notion.com"
  ],
  "engines": [
    "openai",
    "perplexity",
    "gemini"
  ],
  "analyzeSentiment": true,
  "generateReport": true,
  "reportLanguage": "auto",
  "maxConcurrency": 4
}
```

# Actor output Schema

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

One row per prompt × engine: whether your brand was mentioned, its position, competitors, cited sources and the full AI answer.

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

Scorecard overall and per engine: mention rate, average position, share of voice, top cited domains and prompts where your brand is missing.

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

Formatted report with written summary, recommendations, prompt-by-prompt appearance and cited sources. Print to PDF from your browser.

# 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",
    "topic": "note-taking apps for teams",
    "competitors": [
        "Evernote",
        "Obsidian",
        "Coda"
    ],
    "brandDomains": [
        "notion.so",
        "notion.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("matidepa22/ai-visibility-monitor").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",
    "topic": "note-taking apps for teams",
    "competitors": [
        "Evernote",
        "Obsidian",
        "Coda",
    ],
    "brandDomains": [
        "notion.so",
        "notion.com",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("matidepa22/ai-visibility-monitor").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",
  "topic": "note-taking apps for teams",
  "competitors": [
    "Evernote",
    "Obsidian",
    "Coda"
  ],
  "brandDomains": [
    "notion.so",
    "notion.com"
  ]
}' |
apify call matidepa22/ai-visibility-monitor --silent --output-dataset

```

## MCP server setup

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

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/3PEcjqiUpOw0IvCnA/builds/nH17tyIZRV0ugOzNl/openapi.json
