# AI Visibility Tracker: ChatGPT, Perplexity, Gemini (`meridianlabs/ai-visibility-tracker`) Actor

AI visibility tracker and LLM brand monitor: does ChatGPT, Perplexity, Gemini or Claude name your brand? Mentions, rank, cited sources and share of voice vs competitors, per engine. Charged per answer; failures are free.

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

## Pricing

from $8.00 / 1,000 chatgpt or gemini answers

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

Find out whether AI assistants recommend your brand. Give it your brand, a few competitors and the questions your buyers ask. For every question it asks ChatGPT, Perplexity, Gemini and Claude, then tells you who got named, in what order, which websites were cited, and your share of voice on each engine.

ChatGPT and Gemini answers are the ones the apps actually show people, with their citations, not a cheaper API model standing in for them.

### What do you get?

**One row per answer** (prompt x engine):

- **Mentioned or not**, for your brand and each competitor
- **Position**: who was named first, second, third
- **List rank**: your place in the answer's main "top picks" list (#1, #2, ...)
- **Cited**: whether the answer linked to your website, and which of your pages
- **Sources**: every URL and domain the answer cited
- **Sentiment** (experimental): positive, negative, mixed or neutral, from a word list (see below)
- **Other brands named** (ChatGPT): brands in the answer that you aren't tracking yet
- The full answer text, plus the web searches the AI ran where the engine shows them

**One summary row per run**, per engine and across all engines:

- **Share of voice**: of the answers that named any tracked brand, how many named you
- **Mention rate**: % of answers naming you
- **Citation rate**: % of answers citing your site
- **Average position** when you are named
- **Top cited domains**: the sites the AI leans on for your topic, the place to get coverage
- Answers that failed or were skipped, per engine, so you always know how complete the numbers are

**One share-of-voice row per engine x brand**, ready for a chart or a sheet.

### Why this one?

- **Four engines in one run, a fixed price per answer.** No API keys, no AI usage billed on top.
- **Real app answers for ChatGPT and Gemini**, collected by our data provider the way a person sees them, citations included.
- **Your country.** ChatGPT, Gemini and Perplexity answer as if asked from the country you pick (191 countries).
- **Steadier numbers.** AI answers change from one ask to the next. Set "Repeats per prompt" to 2-5 and the summary averages over them.
- **Compare with last time.** Give the run a project name and the summary shows how each number moved since your last run with that name. Schedule it weekly and you have a tracker.
- **Your prompts, exactly.** Nothing is padded with template questions.
- **Failures are free and visible.** A failed or empty answer is a free row with the reason, and the summary counts them per engine. A run never says "done" while quietly missing answers.

### How do I check if ChatGPT mentions my brand?

1. Type your brand, with its website after a comma: `HubSpot, hubspot.com`.
2. Add up to 20 competitors the same way, one per line.
3. Add the questions your buyers ask, one per line, up to 100 per run.
4. Pick the engines (all four by default), the country and the language.
5. Run it. Open the **Summary** tab for share of voice, **Answers** for every answer.

#### How do I track AI visibility every week?

Save your input as a task, set a **project name** (for example `Acme weekly`), and schedule the task weekly in Apify. Each run's summary includes `previousRun` and `changeSinceLastRunPts`, the change in percentage points for share of voice, mention rate and citation rate on every engine. The last summary per project is kept in a store in your own Apify account called `ai-visibility-tracker-history`; delete it any time.

### How much does it cost?

**$0.008 per ChatGPT or Gemini answer, $0.02 per Perplexity or Claude answer**, everything included. One answer = one prompt on one engine (times your repeats).

| Run | Answers | Cost |
|---|---|---|
| 1 prompt, 4 engines | 4 | $0.056 |
| 10 prompts, 4 engines | 40 | $0.56 |
| 10 prompts, ChatGPT and Gemini only | 20 | $0.16 |
| 25 prompts, 4 engines, 3 repeats | 300 | $4.20 |

Not charged: failed answers, empty answers, prompts we can't send, anything past your spending limit or the run's time limit, and the summary and share-of-voice rows. Set a **maximum cost per run** in the run options and the Actor stops asking before it would go over.

Free Apify accounts get up to 8 answers per run (two prompts on four engines). A paid Apify plan has no such limit. One run takes up to 1,000 answers.

### Input example

```json
{
  "brand": "HubSpot, hubspot.com",
  "competitors": ["Zoho CRM, zoho.com, Zoho", "Pipedrive, pipedrive.com", "Salesforce, salesforce.com"],
  "prompts": ["best CRM for small business", "which CRM is easiest for a 5-person sales team"],
  "engines": ["chatgpt", "perplexity", "gemini", "claude"],
  "country": "US",
  "language": "en",
  "samplesPerPrompt": 1,
  "projectName": "HubSpot weekly"
}
```

### Output example

An answer row from a real run (shortened):

```json
{
  "rowType": "answer",
  "prompt": "best CRM for small business",
  "engine": "ChatGPT",
  "status": "ok",
  "brandMentioned": true,
  "brandPosition": 1,
  "brandListRank": 1,
  "brandCited": true,
  "brandCitedUrls": ["https://www.hubspot.com/products/crm"],
  "brandSentiment": "positive",
  "brandsMentioned": ["HubSpot", "Zoho CRM", "Pipedrive", "Salesforce"],
  "otherBrandsNamed": ["Freshsales", "Monday CRM"],
  "citedDomains": ["hubspot.com", "zoho.com", "pipedrive.com", "freshworks.com"],
  "charged": true
}
```

The summary row from the same run (2 prompts on 4 engines, shortened):

```json
{
  "rowType": "summary",
  "brand": "HubSpot",
  "answers": 8,
  "shareOfVoicePct": {"ChatGPT": 28.6, "Perplexity": 28.6, "Gemini": 33.3, "Claude": 28.6, "All engines": 29.6},
  "mentionRatePct": {"ChatGPT": 100, "Perplexity": 100, "Gemini": 100, "Claude": 100, "All engines": 100},
  "citationRatePct": {"ChatGPT": 100, "Perplexity": 50, "Gemini": 0, "Claude": 0, "All engines": 37.5},
  "avgPosition": {"ChatGPT": 1, "Perplexity": 1.5, "Gemini": 1.5, "Claude": 1, "All engines": 1.25}
}
```

### How to read the numbers

- **Share of voice** = answers naming the brand / answers naming any tracked brand. It depends on which competitors you list, so keep the list the same between runs you compare.
- **Mention rate** = answers naming the brand / all answers that came back.
- **Position** = order of first mention among your brand and your competitors. Brands you didn't list don't count here (see "Other brands named").
- **List rank** = the brand's entry number in the answer's main list. The main list is the one whose entries name the most of your tracked brands (a "top picks" list, numbered or not); only the entries' own title lines count, not their sub-points. Empty when the brand has no entry of its own in that list, for example when it is only named in the opening sentence or inside another entry.
- **What counts as text**: what a reader sees. Image captions and link addresses are ignored, so a brand named only in a source URL is not "mentioned"; a link's visible text does count.
- **Brand matching**: whole words, any case, on the name, the other names you give, and the website. `HubSpot` matches "HubSpot's" but not "HubSpotter". If your brand is also a common word, add a more specific name ("monday CRM", "Square payments").
- **Sentiment is experimental.** It comes from a list of positive and negative words in the sentences that name the brand. In our hand check of 40 answers it matched a careful reading about 6 times in 10, mostly by calling praise "neutral" when the praise uses words outside its list. Use it to spot answers worth reading, not as a score.

### Engines

| Engine | What you get | Country |
|---|---|---|
| ChatGPT | The chatgpt.com answer as people see it, with citations and the brands it detected | Yes |
| Gemini | The gemini.google.com answer as people see it, with citations | Yes |
| Perplexity | Perplexity Sonar with live web search, via the official API | Yes |
| Claude | Claude Haiku from its own knowledge, via the official API, no live web search, so no citations | No |

### Limitations

- AI answers vary between asks. Use repeats for numbers you will act on.
- Claude answers from what the model learned, not from today's web, so it shows no sources and ignores the country.
- Prompts are capped at 500 characters (the AI APIs' limit).
- The ChatGPT and Gemini app answers are collected by our data provider; we never log in to or use those apps ourselves.

### FAQ

#### Where does the data come from?

From DataForSEO's AI Optimization API. ChatGPT and Gemini answers come from its LLM Scraper, which reads the answers the consumer apps show. Perplexity and Claude come through its LLM Responses endpoint, which calls the official Perplexity and Anthropic APIs.

#### Is it legal to track what AI assistants say about my brand?

The answers come from DataForSEO, a licensed data provider: ChatGPT and Gemini as their apps show them, Perplexity and Claude through their official APIs. The Actor never logs in to any AI service and collects no personal data, only what the engines say about brands. Check your own use against your local rules.

#### Can I use it with the API, AI agents or MCP?

Yes. Call it through the Apify API with the same JSON input and read the default dataset, or add it as a tool in Apify's MCP server. The summary row is the easiest thing for an agent to read.

#### Does it collect personal data?

No. It sends your questions to AI engines and reads their answers about brands.

#### What happens if a run times out or restarts?

Answers already saved are kept and not charged again; the run picks up where it stopped. If the time limit is close, the remaining answers are listed as skipped (free) and the run still finishes with a summary.

### More from Meridian Labs

- **[Backlink Checker](https://apify.com/meridianlabs/backlink-checker)**: backlinks, referring domains, domain rank and spam score for up to 1,000 domains or URLs per run.
- **[Competitor Keyword Research](https://apify.com/meridianlabs/competitor-keywords)**: every keyword a website ranks for in Google, with position, ranking page, search volume and estimated traffic.
- **[Keyword Search Volume & CPC API + Google Trends](https://apify.com/meridianlabs/keyword-search-volume)**: monthly search volume, CPC, competition, difficulty and intent for keyword lists.
- **[Google Jobs Scraper: Salaries, Apply Links & API](https://apify.com/meridianlabs/google-jobs-scraper)**: every job Google Jobs shows for a search, up to 200, with full descriptions, every apply link and salary normalised to yearly and hourly. $1.50 per 1,000 jobs.
- **[Google Trends Scraper & API](https://apify.com/meridianlabs/google-trends-scraper)**: interest over time, by region and rising related searches for hundreds of keywords, as a maintained pytrends alternative. $5 per 1,000 keyword lookups.
- **[Facebook Ads Library Scraper](https://apify.com/meridianlabs/facebook-ads-library-scraper)**: every ad a competitor runs on Facebook and Instagram, with days running and a plain-English summary per advertiser. $0.10 per 1,000 ads.
- **[YouTube Transcript API & Scraper](https://apify.com/meridianlabs/youtube-transcripts)**: full transcripts with timestamps in the video's original language, for videos and Shorts. $3 per 1,000 transcripts; videos without captions are free.
- **[Greenhouse, Lever & Ashby Jobs Scraper](https://apify.com/meridianlabs/greenhouse-lever-ashby-jobs-scraper)**: open jobs from companies on six hiring systems, with salary normalised to min, max, currency and period. $2 per 1,000 jobs.
- **[Instagram Transcript Scraper: Reels Transcript API](https://apify.com/meridianlabs/instagram-reels-transcript)**: what is said in each Instagram Reel, as text with timestamps and SRT subtitles, in its original language. $3 per 1,000 reels; music-only reels free.

### Support

Something looks wrong, or you need a field we don't return? Open an issue on the **Issues** tab with the input you used. We read every one.

If this saved you time, a rating helps others find it; if something's off, open an issue and we'll fix it fast.

# Actor input Schema

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

Your brand name, then optionally its website and other names, separated by commas: 'HubSpot, hubspot.com, HubSpot CRM'. The website is used to spot when an answer cites you.

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

Up to 20, one per line, same format: 'Pipedrive, pipedrive.com'. Share of voice is worked out across your brand and these.

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

Optional: product names or spellings that should count as your brand.

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

Optional: more domains of yours (subdomains are included automatically).

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

The questions your buyers ask AI assistants, one per line, up to 100 per run and 500 characters each, e.g. 'best CRM for a small agency'. Each prompt is asked once per engine (times samplesPerPrompt).

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

Each engine is one charged answer per prompt. Default: all four.

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

2-letter code the answers are asked from: US, GB (or UK), DE, AU, CA, IN... 191 countries. Claude ignores it (no web search).

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

Language code: en, de, fr, es, pt, it, nl, ja...

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

AI answers change from one ask to the next. Ask each prompt 2-5 times per engine for steadier numbers (each repeat is a charged answer).

## `includeAnswerText` (type: `boolean`):

Keep the full answer (markdown) in each row. Turn off for smaller exports.

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

Optional. Give the same name on every run (e.g. 'Acme weekly') and the summary shows the change since the last run with that name. Kept in a store in your own Apify account ('ai-visibility-tracker-history'); delete it any time.

## `failOnErrors` (type: `boolean`):

Off: failed answers are free error rows and the run succeeds. On: the run is marked failed (useful for schedules that alert).

## Actor input object example

```json
{
  "brand": "HubSpot, hubspot.com",
  "competitors": [
    "Zoho CRM, zoho.com, Zoho",
    "Pipedrive, pipedrive.com",
    "Salesforce, salesforce.com"
  ],
  "brandAliases": [],
  "brandDomains": [],
  "prompts": [
    "best CRM for small business",
    "which CRM is easiest for a 5-person sales team"
  ],
  "engines": [
    "chatgpt",
    "perplexity",
    "gemini",
    "claude"
  ],
  "country": "US",
  "language": "en",
  "samplesPerPrompt": 1,
  "includeAnswerText": true,
  "failOnErrors": false
}
```

# Actor output Schema

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

Share of voice, mention rate, citation rate and average position per engine (dataset view 'summary').

## `shareOfVoice` (type: `string`):

One row per engine x brand (dataset view 'shareOfVoice').

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

One row per AI answer (dataset view 'answers').

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

Every field of every row, including answer text and sources.

# 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": "HubSpot, hubspot.com",
    "competitors": [
        "Zoho CRM, zoho.com, Zoho",
        "Pipedrive, pipedrive.com",
        "Salesforce, salesforce.com"
    ],
    "prompts": [
        "best CRM for small business",
        "which CRM is easiest for a 5-person sales team"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("meridianlabs/ai-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": "HubSpot, hubspot.com",
    "competitors": [
        "Zoho CRM, zoho.com, Zoho",
        "Pipedrive, pipedrive.com",
        "Salesforce, salesforce.com",
    ],
    "prompts": [
        "best CRM for small business",
        "which CRM is easiest for a 5-person sales team",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("meridianlabs/ai-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": "HubSpot, hubspot.com",
  "competitors": [
    "Zoho CRM, zoho.com, Zoho",
    "Pipedrive, pipedrive.com",
    "Salesforce, salesforce.com"
  ],
  "prompts": [
    "best CRM for small business",
    "which CRM is easiest for a 5-person sales team"
  ]
}' |
apify call meridianlabs/ai-visibility-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,meridianlabs/ai-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/NvxHbmD5m5FzAdxla/builds/RCF6OiaaHJWuqy0Xj/openapi.json
