# AI Brand Visibility Tracker (ChatGPT, Gemini...) (`tiger19935/ai-brand-visibility-tracker`) Actor

AI brand visibility tracker: run prompt sets across OpenAI, Gemini, Perplexity and Claude web search via official APIs. Get mentions, rank, sentiment, cited URLs and share of voice vs competitors, with history and Slack reports. Bring your own keys, $0.04 per check.

- **URL**: https://apify.com/tiger19935/ai-brand-visibility-tracker.md
- **Developed by:** [Andrew Boiko](https://apify.com/tiger19935) (community)
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $28.00 / 1,000 provider checks

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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?

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, Gemini...)

AI brand visibility tracker that uses official provider APIs with web search (OpenAI Responses API, Google Gemini Search grounding, Perplexity Sonar and Anthropic Claude web search) instead of fragile UI scraping, so results are repeatable and fast. Define your prompts, locales and competitors once, then run it weekly and watch your AI visibility move.

For every prompt x locale x provider combination you get: was your brand mentioned, in which position among the brands you track, a sentiment label, the cited URLs and domains, and share of voice against your competitors. A history store turns each run into a delta against the previous one, and an optional Slack webhook posts the weekly report.

### What does AI Brand Visibility Tracker do?

This actor answers one question: when someone asks an AI assistant about your category, does your brand show up, and compared to whom? It is built for GEO (generative engine optimization), AEO and LLM SEO monitoring.

- **Prompt sets x locales x providers.** Each combination is one "provider check". The actor sends your prompt to the provider's official API with web search switched on, and the user's country is passed where the API supports it.
- **Mention detection.** Your brand and its aliases are matched case-insensitively on word boundaries, so "Notion" does not match "notional". Competitors are matched the same way.
- **Rank.** The order of first mention among the brands you track (1 = mentioned first). Brands you do not list are not ranked.
- **Sentiment.** A simple English keyword lexicon applied to the sentences that mention your brand. It is a heuristic, labelled as such in the output, not a trained model.
- **Citations.** Every URL the provider returned as a source, plus the list of cited domains and a flag for whether one of your own domains was cited.
- **Share of voice.** Per run, per provider, per prompt and per locale: the entity's mentioning checks divided by the mentioning checks of all tracked brands.
- **History and delta.** Each report is saved in a named key-value store (`ai-brand-visibility-history`). The next run shows the change in mention rate, share of voice and average rank.
- **Slack report.** Paste an incoming webhook URL and schedule the actor weekly.

Google AI Overviews are not included in this version. There is no official API for them, and this actor deliberately does not scrape Google results.

#### Bring your own keys

By default you paste your own provider API keys. The AI providers then bill your own accounts directly and this actor bills only its event prices (below). You only need keys for the providers you want to query. A provider without a key is skipped with a warning and is never charged.

### Why use AI Brand Visibility Tracker?

1. **Official APIs, not scraped chat windows.** No logins, cookies, browser sessions or proxies, so there is nothing to block and runs are deterministic in shape. A default run with 12 checks finishes in about two to four minutes.
2. **Everything in one run.** Prompt sets, locales, four providers, competitors, share of voice, sentiment, cited domains, history and a Slack report. Many Store actors cover a single provider and return raw answers only.
3. **Pay per result, no subscription.** $0.04 per provider check and $0.15 per report on the FREE tier, with volume discounts on paid plans. Dedicated GEO platforms are typically priced as monthly subscriptions.
4. **You decide what is billed.** Failed checks, skipped providers and empty answers are never charged, and `maxItems` caps the number of checks in a run.

#### How results differ from consumer chat apps

API answers are not identical to what a person sees in the consumer apps. Perplexity Sonar and Gemini with Google Search grounding are the same model families as their consumer products; for OpenAI and Anthropic the API web-search tool is used, which is a different surface from the ChatGPT or Claude apps. Treat the numbers as a consistent, repeatable measurement of each provider's search-enabled answers, best used as a trend over time.

### How much does it cost to scrape AI visibility?

You pay per event. Prices per single event:

| Event | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|
| provider-check (one prompt, one provider, one locale) | $0.04 | $0.036 | $0.032 | $0.028 |
| report (one aggregated report per run) | $0.15 | $0.135 | $0.12 | $0.105 |

Examples at FREE prices:

- 1,000 provider checks = $40 (plus $0.15 per run if the report is on).
- 3 prompts x 4 providers x 1 locale = 12 checks = $0.48 + $0.15 report = $0.63 per weekly run, about $2.70 per month.

Provider API usage is billed by OpenAI, Google, Perplexity and Anthropic to the key you paste, at their own rates. Check their pricing pages; web-search calls are usually the largest part.

Free Apify plans are limited to 25 results per run (checks and the report row count). After that the run ends normally with a soft message. Use `maxItems` to cap checks and the Apify `maxTotalChargeUsd` run option to cap spend: when the limit is reached, the actor stops gracefully.

### Input

| Field | Type | Description |
|---|---|---|
| `brand` | string | Brand to track (required). |
| `brandAliases` | array | Other names that count as a mention. |
| `brandDomains` | array | Your domains, to detect whether answers cite your site. |
| `competitors` | array | Competitor names; add aliases after pipes: `Evernote \| Evernote Business`. |
| `prompts` | array | Questions to ask (required). |
| `locales` | array | Locale codes such as `en-US`, `de-DE`. Default `en-US`. |
| `providers` | array | `perplexity`, `openai`, `gemini`, `anthropic`. |
| `perplexityApiKey`, `openaiApiKey`, `geminiApiKey`, `anthropicApiKey` | secret | Your own provider keys. |
| `useOwnerKeys` | boolean | Use keys configured by the actor owner, if any. Default off. |
| `perplexityModel`, `openaiModel`, `geminiModel`, `anthropicModel` | string | Model names; change them if a default is retired. |
| `maxItems` | integer | Max provider checks per run. Default 20. |
| `generateReport` | boolean | Add one aggregated report row. Default on. |
| `trackHistory` | boolean | Save a snapshot for deltas. Default on. |
| `historyLabel` | string | Keep separate histories for the same brand. |
| `slackWebhookUrl` | secret | Post the report summary to Slack. |
| `includeAnswerText` | boolean | Store the answer text (max 6,000 chars). |
| `concurrency`, `requestTimeoutSecs` | integer | Parallel requests and per-request timeout. |

Quick check on two providers:

```json
{
  "brand": "Notion",
  "brandDomains": ["notion.so"],
  "competitors": ["Evernote", "Obsidian", "Coda"],
  "prompts": ["What are the best note-taking apps for teams?"],
  "locales": ["en-US"],
  "providers": ["perplexity", "gemini"],
  "perplexityApiKey": "pplx-...",
  "geminiApiKey": "AIza..."
}
```

Multi-locale share of voice with a Slack report:

```json
{
  "brand": "Notion",
  "brandAliases": ["Notion AI"],
  "competitors": ["Evernote", "Obsidian | Obsidian MD", "Coda"],
  "prompts": ["Best note-taking apps for teams", "Notion alternatives"],
  "locales": ["en-US", "de-DE", "fr-FR"],
  "providers": ["openai", "perplexity", "gemini", "anthropic"],
  "openaiApiKey": "sk-...", "perplexityApiKey": "pplx-...", "geminiApiKey": "AIza...", "anthropicApiKey": "sk-ant-...",
  "maxItems": 100,
  "slackWebhookUrl": "https://hooks.slack.com/services/..."
}
```

### Output example

Illustrative example, not from a real run. One dataset row per check (`type: "provider-check"`):

```json
{
  "type": "provider-check",
  "checkedAt": "2026-10-19T09:00:00.000Z",
  "brand": "Notion",
  "prompt": "What are the best note-taking apps for teams?",
  "locale": "en-US",
  "provider": "perplexity",
  "model": "sonar",
  "brandMentioned": true,
  "brandMentionCount": 2,
  "brandRank": 2,
  "listedBrandsInOrder": ["Obsidian", "Notion"],
  "competitors": [{ "name": "Evernote", "mentioned": false, "count": 0, "rank": null }, { "name": "Obsidian", "mentioned": true, "count": 1, "rank": 1 }],
  "sentimentLabel": "positive",
  "sentimentScore": 1,
  "sentimentDetail": { "positiveHits": 2, "negativeHits": 0, "sentencesAnalysed": 2, "method": "english-lexicon-heuristic" },
  "citations": [{ "url": "https://notion.so/product", "title": "Notion", "domain": "notion.so" }],
  "citedDomains": ["notion.so"],
  "brandDomainCited": true,
  "answer": "Obsidian is great for local notes. Notion is excellent for teams..."
}
```

The report row (`type: "report"`) contains `brand` (mention rate, share of voice, average rank), `entities` sorted by share of voice, `sentimentDistribution`, `topCitedDomains`, breakdowns by provider, prompt and locale, and `delta` against the previous snapshot (a negative `avgRank` change means you moved up). The same report is stored in the `OUTPUT` record together with counts, charged events and warnings.

### How to use AI Brand Visibility Tracker (tutorial)

1. Create API keys with the providers you want (any subset of Perplexity, OpenAI, Google AI Studio, Anthropic). Make sure web search is enabled for your OpenAI and Anthropic accounts.
2. Open the actor, enter your brand, aliases, own domains and two to five competitors.
3. Add 3 to 10 prompts a real buyer would type, and one or more locales.
4. Paste your keys, keep `maxItems` low for the first run and click Start. The overview table shows one row per check plus the report.
5. Create a weekly schedule with the same input. Add a Slack webhook to receive the report, and compare the `delta` block from week to week.

### Run via API

```bash
curl -X POST "https://api.apify.com/v2/acts/tiger19935~ai-brand-visibility-tracker/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"brand":"Notion","competitors":["Evernote","Obsidian"],"prompts":["Best note-taking apps for teams"],"providers":["perplexity"],"perplexityApiKey":"pplx-..."}'
```

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('tiger19935/ai-brand-visibility-tracker').call({
  brand: 'Notion', competitors: ['Evernote', 'Obsidian'],
  prompts: ['Best note-taking apps for teams'], providers: ['perplexity'], perplexityApiKey: process.env.PPLX_KEY,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

MCP: the actor can be called from any MCP client through the Apify MCP server; all main inputs are plain arrays and strings.

### Integrations

Use Apify integrations to connect it to n8n, Make and Zapier, push the dataset to Google Sheets, or call a webhook when a run finishes. The built-in Slack webhook posts the weekly summary without any extra tooling. Schedule it weekly from the Apify Console.

### Legal / ethical use

The actor calls official provider APIs with keys you own, under those providers' terms of use, and does not scrape websites or log in anywhere. It processes only the prompts you send and the public answers and source URLs the providers return. Do not put personal data into prompts. You are responsible for complying with each provider's terms and for how you use the results.

### FAQ and support

**Are results the same as the consumer ChatGPT app?** Not identical. Perplexity Sonar and Gemini grounding use the same model families as their consumer products; for OpenAI and Anthropic the API web-search tool is used. See the section above.

**How is pricing calculated?** Per provider check (one prompt on one provider and locale) and per report. Provider API costs are billed to your own keys by default.

**Can I compare against competitors?** Yes. Add competitor names (and aliases after pipes) and the report shows share of voice, rank and mention rate per competitor, provider, prompt and locale.

**Does it track Google AI Overviews?** Not in this version.

**What if a model name is retired?** The provider is skipped with a clear error naming the input field to change (for example `openaiModel`). Nothing is charged.

**Is sentiment reliable?** It is a transparent keyword heuristic on English text. Use it as a rough signal and read the answer text for important prompts.

**Why is my brand not detected?** Add alternative spellings to `brandAliases`. Matching is whole-word and case-insensitive.

**Can I use your keys instead of mine?** Only if the owner has configured them and you set `useOwnerKeys`; by default you bring your own.

Questions or a provider that changed its API? Open the Issues tab; replies usually within 12 hours.

### More tools by the same author

- [Prozorro & TED Tenders Scraper](https://apify.com/tiger19935/prozorro-ted-tenders-scraper) - public tenders from Ukraine and the EU
- [Billing & Payment Stack Detector](https://apify.com/tiger19935/billing-stack-detector) - which payment gateway a website uses
- [Website Technology Detector](https://apify.com/tiger19935/website-technology-detector) - tech stack of any site
- [Decision-Maker Contacts](https://apify.com/tiger19935/decision-maker-contacts) - people and roles at a company

### Related searches

ai visibility tracker, geo tracking, aeo monitoring, chatgpt brand mentions, perplexity brand tracking, ai overview tracker, share of voice ai, llm seo monitoring, generative engine optimization, ai search ranking, brand mention in chatgpt, ai citations tracker.

# Changelog

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

# Actor input Schema

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

The brand to track, exactly as people write it (for example Notion). Matching is case-insensitive and whole-word.

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

Other spellings or product names that count as a mention of your brand (for example Notion AI). Whole-word, case-insensitive.

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

Your own domains (for example notion.so). Used to tell whether an answer cites your website. Leave empty to skip.

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

Competitor names for rank and share of voice. Add aliases after pipes, for example: Evernote | Evernote Business.

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

Questions a buyer might ask an AI assistant, one per line. Each prompt is checked on every selected provider and locale (one billed provider-check each).

## `locales` (type: `array`):

Locale codes such as en-US, de-DE, fr-FR. The country is passed to each provider as the user location where supported, and the answer language is requested.

## `providers` (type: `array`):

Which AI engines to query. A provider is skipped with a warning if no API key is available for it.

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

Your own Perplexity API key. Stored as a secret, never logged.

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

Your own OpenAI API key (needs access to the Responses API web_search tool). Stored as a secret, never logged.

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

Your own Google AI Studio / Gemini API key. Stored as a secret, never logged.

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

Your own Anthropic API key (web search must be enabled for your organization). Stored as a secret, never logged.

## `useOwnerKeys` (type: `boolean`):

Only works if the actor owner has configured provider keys as environment variables. Off by default: with your own keys you pay only this actor's event prices.

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

Perplexity model name. Change it if the default is retired.

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

OpenAI model that supports the web_search tool in the Responses API. Change it if the default is retired.

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

Gemini model that supports Google Search grounding. Change it if the default is retired.

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

Claude model that supports the web search tool. Change it if the default is retired.

## `maxItems` (type: `integer`):

Upper bound on prompt x locale x provider checks per run. Also caps your spend. Free Apify plans are limited to 25 results per run.

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

Adds one report row with mention rate, rank, sentiment, share of voice, top cited domains and the change since the previous run. Billed as one report event.

## `trackHistory` (type: `boolean`):

Stores a snapshot in a named key-value store so the next run can show what changed.

## `historyLabel` (type: `string`):

Optional label to keep separate histories for the same brand (for example weekly-us). Defaults to the brand name.

## `slackWebhookUrl` (type: `string`):

Optional Slack incoming webhook. The report summary is posted there after each run. Schedule the actor weekly for a weekly report.

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

Store the AI answer (truncated to 6,000 characters) in each row.

## `concurrency` (type: `integer`):

Parallel provider requests. Lower it if you hit provider rate limits.

## `requestTimeoutSecs` (type: `integer`):

Timeout per provider request. Web-search answers can take 20 to 60 seconds.

## Actor input object example

```json
{
  "brand": "Notion",
  "brandAliases": [],
  "brandDomains": [
    "notion.so"
  ],
  "competitors": [
    "Evernote",
    "Obsidian",
    "Coda"
  ],
  "prompts": [
    "What are the best note-taking apps for teams?"
  ],
  "locales": [
    "en-US"
  ],
  "providers": [
    "perplexity",
    "openai",
    "gemini",
    "anthropic"
  ],
  "useOwnerKeys": false,
  "perplexityModel": "sonar",
  "openaiModel": "gpt-4.1-mini",
  "geminiModel": "gemini-2.5-flash",
  "anthropicModel": "claude-haiku-4-5",
  "maxItems": 20,
  "generateReport": true,
  "trackHistory": true,
  "includeAnswerText": true,
  "concurrency": 3,
  "requestTimeoutSecs": 90
}
```

# Actor output Schema

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

One row per prompt x locale x provider check, plus one aggregated report row.

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

Counts, charged events, estimated cost, warnings and the report.

# 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",
    "brandAliases": [],
    "brandDomains": [
        "notion.so"
    ],
    "competitors": [
        "Evernote",
        "Obsidian",
        "Coda"
    ],
    "prompts": [
        "What are the best note-taking apps for teams?"
    ],
    "locales": [
        "en-US"
    ],
    "providers": [
        "perplexity",
        "openai",
        "gemini",
        "anthropic"
    ],
    "useOwnerKeys": false,
    "perplexityModel": "sonar",
    "openaiModel": "gpt-4.1-mini",
    "geminiModel": "gemini-2.5-flash",
    "anthropicModel": "claude-haiku-4-5",
    "maxItems": 20,
    "generateReport": true,
    "trackHistory": true,
    "includeAnswerText": true,
    "concurrency": 3,
    "requestTimeoutSecs": 90
};

// Run the Actor and wait for it to finish
const run = await client.actor("tiger19935/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": "Notion",
    "brandAliases": [],
    "brandDomains": ["notion.so"],
    "competitors": [
        "Evernote",
        "Obsidian",
        "Coda",
    ],
    "prompts": ["What are the best note-taking apps for teams?"],
    "locales": ["en-US"],
    "providers": [
        "perplexity",
        "openai",
        "gemini",
        "anthropic",
    ],
    "useOwnerKeys": False,
    "perplexityModel": "sonar",
    "openaiModel": "gpt-4.1-mini",
    "geminiModel": "gemini-2.5-flash",
    "anthropicModel": "claude-haiku-4-5",
    "maxItems": 20,
    "generateReport": True,
    "trackHistory": True,
    "includeAnswerText": True,
    "concurrency": 3,
    "requestTimeoutSecs": 90,
}

# Run the Actor and wait for it to finish
run = client.actor("tiger19935/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": "Notion",
  "brandAliases": [],
  "brandDomains": [
    "notion.so"
  ],
  "competitors": [
    "Evernote",
    "Obsidian",
    "Coda"
  ],
  "prompts": [
    "What are the best note-taking apps for teams?"
  ],
  "locales": [
    "en-US"
  ],
  "providers": [
    "perplexity",
    "openai",
    "gemini",
    "anthropic"
  ],
  "useOwnerKeys": false,
  "perplexityModel": "sonar",
  "openaiModel": "gpt-4.1-mini",
  "geminiModel": "gemini-2.5-flash",
  "anthropicModel": "claude-haiku-4-5",
  "maxItems": 20,
  "generateReport": true,
  "trackHistory": true,
  "includeAnswerText": true,
  "concurrency": 3,
  "requestTimeoutSecs": 90
}' |
apify call tiger19935/ai-brand-visibility-tracker --silent --output-dataset

```

## MCP server setup

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