# AI Brand Visibility Tracker: ChatGPT, Perplexity, Gemini (`lanternlane-data/ai-brand-visibility-tracker`) Actor

See how often AI assistants mention, rank and cite your brand vs competitors. Asks your buyer questions to OpenAI GPT, Perplexity, Gemini, Claude and more via official APIs with live web search. Share of voice, top-3 rate, sources, sentiment and run-over-run change.

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

## Pricing

from $20.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.

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 Brand Visibility Tracker: ChatGPT, Perplexity, Gemini, Claude

### 🔦 What is the AI Brand Visibility Tracker?

When a buyer asks an AI assistant "what's the best X?", does it name your brand? In what position? Does it link to your site, or to a competitor's?

This Actor asks your buyer questions to several AI models through their **official APIs** (with live web search on), then measures for every answer:

- **Mentioned or not**, how many times, and the sentence it appears in
- **Rank among brands**: 1 = your brand is the first brand named in the answer
- **List position**: "#2 in the list" when the answer is a numbered or bulleted list
- **Cited**: whether your domain is among the sources the model used
- **Share of voice** against the competitors you list
- **Sentiment** and a one-line summary of how the answer describes you (optional)
- **Other brands the AI recommends** that you didn't list, so you find competitors you weren't tracking

Plus a **summary** per model and per prompt, the most cited domains (the pages AI models are learning from in your niche), and the **change since your last run**, so a weekly schedule becomes a visibility trend line.

No scraping of chatbot websites, no logins, no API keys required.

### 🎯 Why use it

- **GEO / AEO reporting**: share-of-voice numbers for clients or your own brand, broken down by model.
- **Content strategy**: the `topCitedDomains` list shows which review sites and publications the models trust for your category. Get featured there.
- **Competitive intelligence**: see which competitors AI assistants push, and how they describe them.
- **Launch tracking**: schedule it weekly and watch mention rate move after a PR push or new content.

### ⚙️ How it works

1. Each prompt is sent to each selected model `runsPerPrompt` times. AI answers vary, so 2-3 runs give steadier rates.
2. With **web search** on, OpenAI, Gemini, Claude and Grok use their providers' native search and Perplexity Sonar uses its own, so answers and cited sources come close to what users see in those apps. Turn it off to test what models "know" from training alone.
3. Mentions are matched on the brand name, your aliases and your domain. Matching is word-boundary aware ("On" won't match "Online") and handles straight and curly apostrophes.
4. An optional second pass with a small, cheap model reads each answer for sentiment and other brand names.

Models are reached through OpenRouter, either through Apify's own OpenRouter proxy, billed to your Apify account, or through your own OpenRouter key if you add one.

### ⬇️ Input

| Field | What to enter |
|---|---|
| `brand` | `Allbirds \| allbirds.com`. Add aliases and domains after a `\|`. |
| `prompts` | Real buyer questions **without** your brand name, e.g. "best wool shoes for travel". |
| `competitors` | `Veja \| veja-store.com`, one per line (max 25). |
| `models` | Pick from OpenAI GPT-5 mini / GPT-5.1, Perplexity Sonar / Sonar Pro, Gemini 2.5 Flash, Claude Haiku 4.5, Grok 4 Fast, DeepSeek, Llama. Add any other OpenRouter model ID in `customModels`. |
| `webSearch` | On by default. |
| `location` | Optional market, e.g. "United Kingdom". |
| `runsPerPrompt` | 1-5. |
| `aiAnalysis` | Sentiment and unlisted-brand discovery (on by default). |
| `maxLlmCostUsd` | Hard stop for model spend per run (default $2). |
| `trackChanges` | Compare with the previous run of the same brand, prompts and models. |
| `openRouterApiKey` | Optional. Your own key; stored encrypted as a secret input. |

Example:

```json
{
  "brand": "Allbirds | allbirds.com",
  "prompts": ["What are the best sustainable sneakers for everyday wear?", "Most comfortable wool shoes for travel"],
  "competitors": ["Veja | veja-store.com", "Rothy's | rothys.com", "On Running | on.com"],
  "models": ["openai/gpt-5-mini", "perplexity/sonar", "google/gemini-2.5-flash", "anthropic/claude-haiku-4.5"],
  "runsPerPrompt": 2,
  "location": "United States"
}
```

### ⬆️ Output

One dataset row per prompt × model × run (excerpt from a real run, answer shortened):

```json
{
  "prompt": "What are the best sustainable sneakers for everyday wear?",
  "model": "google/gemini-2.5-flash",
  "modelLabel": "Google Gemini 2.5 Flash",
  "webSearch": true,
  "status": "ok",
  "brandMentioned": true,
  "brandMentionCount": 3,
  "brandRank": 1,
  "brandListPosition": 1,
  "brandCited": false,
  "brandSentiment": "positive",
  "brandDescription": "Praised for comfort and eco-friendly materials like merino wool; Certified B Corp.",
  "shareOfVoice": 0.3333,
  "entitiesInOrder": ["Allbirds", "Rothy's", "Veja"],
  "competitors": [{"name": "Veja", "mentioned": true, "mentionCount": 2, "rank": 3, "listPosition": 4, "cited": false}],
  "otherBrandsMentioned": ["Cariuma", "Thousand Fell", "Native Shoes"],
  "citations": [{"url": "https://www.thegoodtrade.com/...", "domain": "thegoodtrade.com", "title": "..."}],
  "answer": "Here are some of the best sustainable sneakers...",
  "llmCostUsd": 0.0104,
  "checkedAt": "2026-10-08T14:49:40Z"
}
```

The `SUMMARY` record in the run's key-value store contains:

- `overall`, `byModel`, `byPrompt`: mention rate, top-3 rate, average rank, citation rate, share of voice, sentiment counts and the same metrics for every competitor
- `topCitedDomains`, `otherBrandsMentioned`
- `changeSincePreviousRun`: deltas versus your last comparable run

Failed checks appear as rows with `status: "error"` and are never charged.

### 💰 Cost

- **Actor**: $0.02 per successful prompt check, pay-per-event (see the pricing table below). Failed checks are free.
- **AI model usage** is passed through at the model provider's price via Apify's OpenRouter proxy (or billed by OpenRouter if you use your own key). A typical check with web search costs about **$0.005-0.015** in model usage, and the optional analysis pass adds about $0.0003. The run log and every row show the exact model cost.
- Note: Apify's OpenRouter proxy charges accounts on the **free Apify plan 10x** the model price. If you're on the free plan and run more than a handful of checks, add your own OpenRouter key.
- `maxLlmCostUsd` stops the run once model spend reaches your limit.

### 💡 Tips

- Use 10-30 prompts that match real buying intent ("best X for Y", "X vs Y", "alternatives to Z"). Avoid putting your own brand in the prompt unless you're testing brand perception specifically.
- Run 2-3 times per prompt before drawing conclusions. Single answers are noisy.
- Schedule weekly with the same input to build a trend. `changeSincePreviousRun` fills in from the second run.
- These are answers from the models' APIs. Consumer apps (ChatGPT, Gemini app, Perplexity.ai) can add personalization and other features, so treat results as a strong, repeatable proxy, not a pixel-perfect copy of any one user's screen.

### 🔌 Use it via API, Python or integrations

Run it from the Apify Console, on a schedule, or from code with the Apify API, the Python or JavaScript `apify-client`, or MCP. Connect results to Google Sheets, Slack, Zapier, Make, n8n or a webhook from the **Integrations** tab.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("lanternlane-data/ai-brand-visibility-tracker").call(run_input={"brand": "Allbirds | allbirds.com", "prompts": ["What are the best sustainable sneakers?"], "competitors": ["Veja | veja-store.com"]})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

### ❓ FAQ

**Is this allowed?** Yes. The Actor only calls official, paid model APIs under their standard terms. It doesn't scrape chatbot websites or automate logins.

**Which permission level does it need?** Limited permissions. It reads and writes only its own run storage and one named store for run-to-run comparison.

**Can AI agents use it?** Yes. The input is plain JSON and the output is structured, so it works well from the Apify MCP server or the API.

### 🏮 More from Lantern Lane Data

**Jobs & hiring data** is our focus: job postings straight from employers' applicant tracking systems and official public feeds, in one consistent schema. More ATS platforms and hiring-signal tools are on the way.

- 💼 [ATS Jobs Scraper](https://apify.com/lanternlane-data/careers-page-jobs-aggregator): Every open job from 7 ATS platforms (Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Workable, Recruitee) in one schema, with new and closed job alerts.
- 🌍 [Remote Jobs Scraper](https://apify.com/lanternlane-data/remote-jobs-aggregator): Remote jobs from 7 boards via their official public feeds, deduplicated, with salary and location filters.

**Other tools**

- 🛍️ [Shopify Products Scraper](https://apify.com/lanternlane-data/shopify-store-products-scraper): Every product, price, variant and stock level from any Shopify store, with price-change tracking.
- 🗺️ [Sitemap URL Extractor](https://apify.com/lanternlane-data/sitemap-url-extractor): Every URL from any website's XML sitemaps, with lastmod, hreflang and new-page alerts.

***

Built and maintained by **Lantern Lane Data**. Questions or feature requests: open an issue on the Actor's Issues tab.

# Changelog

This Actor's version history is a separate document: https://apify.com/lanternlane-data/ai-brand-visibility-tracker/changelog.md

# Actor input Schema

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

The brand, company or product to track. Optional aliases and domain can be added with " | ", e.g. "Allbirds | All Birds | allbirds.com".

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

Questions a real customer might ask an AI assistant. Don't name your brand in them if you want to measure organic visibility. One check = one prompt x one model x one run.

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

Competitor brands to benchmark against, same format as the brand field, e.g. "Veja | veja-store.com". Max 25.

## `models` (type: `array`):

Which AI assistants to ask. Each model is queried through its official API (via OpenRouter).

## `customModels` (type: `array`):

Any other OpenRouter model ID, e.g. "mistralai/mistral-medium-3.1". See openrouter.ai/models.

## `webSearch` (type: `boolean`):

On = models answer with live web search (closest to what ChatGPT search, Gemini and Perplexity show users, and gives you cited sources). Off = answers from the model's training data only (cheaper). Perplexity always searches.

## `location` (type: `string`):

e.g. "United Kingdom" or "Berlin, Germany". Tells the model where the user is, for local recommendations.

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

AI answers vary. Asking 2-3 times per model gives more stable mention rates.

## `aiAnalysis` (type: `boolean`):

Adds a cheap second AI pass per answer: sentiment toward your brand, a one-line description of how it's portrayed, and other brands the answer recommends that you didn't list as competitors.

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

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

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

Your website domains, used to detect when an AI answer cites your site.

## `searchResults` (type: `integer`):

Max web results each model can use (where the search engine supports it).

## `maxChecks` (type: `integer`):

Safety cap on prompt x model x run combinations.

## `maxLlmCostUsd` (type: `number`):

Stops asking new questions once the AI model usage for this run reaches this amount. 0 = no limit.

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

How many AI requests run at the same time.

## `trackChanges` (type: `boolean`):

Stores each run's summary and reports the change in mention, top-3 and citation rates versus the last run with the same brand, prompts and models. Ideal with a weekly schedule.

## `stateStoreName` (type: `string`):

Named key-value store used for run-to-run comparison.

## `openRouterApiKey` (type: `string`):

Leave empty to pay for model usage through your Apify account (no other account needed). If you add your own OpenRouter key, model usage is billed by OpenRouter instead. Stored encrypted.

## Actor input object example

```json
{
  "brand": "Allbirds | allbirds.com",
  "prompts": [
    "What are the best sustainable sneakers for everyday wear?",
    "Most comfortable wool shoes for travel"
  ],
  "competitors": [
    "Veja | veja-store.com",
    "Rothy's | rothys.com",
    "On Running | on.com"
  ],
  "models": [
    "openai/gpt-5-mini",
    "perplexity/sonar",
    "google/gemini-2.5-flash",
    "anthropic/claude-haiku-4.5"
  ],
  "webSearch": true,
  "runsPerPrompt": 1,
  "aiAnalysis": true,
  "searchResults": 5,
  "maxChecks": 200,
  "maxLlmCostUsd": 2,
  "maxConcurrency": 4,
  "trackChanges": true,
  "stateStoreName": "ai-brand-visibility-tracker"
}
```

# Actor output Schema

## `checks` (type: `string`):

No description

## `summary` (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": "Allbirds | allbirds.com",
    "prompts": [
        "What are the best sustainable sneakers for everyday wear?",
        "Most comfortable wool shoes for travel"
    ],
    "competitors": [
        "Veja | veja-store.com",
        "Rothy's | rothys.com",
        "On Running | on.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lanternlane-data/ai-brand-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": "Allbirds | allbirds.com",
    "prompts": [
        "What are the best sustainable sneakers for everyday wear?",
        "Most comfortable wool shoes for travel",
    ],
    "competitors": [
        "Veja | veja-store.com",
        "Rothy's | rothys.com",
        "On Running | on.com",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("lanternlane-data/ai-brand-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": "Allbirds | allbirds.com",
  "prompts": [
    "What are the best sustainable sneakers for everyday wear?",
    "Most comfortable wool shoes for travel"
  ],
  "competitors": [
    "Veja | veja-store.com",
    "Rothy'\''s | rothys.com",
    "On Running | on.com"
  ]
}' |
apify call lanternlane-data/ai-brand-visibility-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lanternlane-data/ai-brand-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/4dcuXoKza25dCGRgw/builds/9ZgxaSheXajzRaOS7/openapi.json
