# AI Brand Visibility & Share of Voice: ChatGPT, Perplexity (`koalabed/ai-brand-visibility`) Actor

Measure how often AI answers name your brand vs competitors. Repeated samples across ChatGPT, Perplexity and Gemini give visibility %, AI share of voice, answer position, cited sources and change since your last run. Pay per answer.

- **URL**: https://apify.com/koalabed/ai-brand-visibility.md
- **Developed by:** [Sama Alabed](https://apify.com/koalabed) (community)
- **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 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

## AI Brand Visibility & Share of Voice: ChatGPT, Perplexity

**When people ask AI assistants about your market, how often is your brand named, and how does that compare with your competitors?**

This Actor asks ChatGPT, Perplexity and Gemini the questions your customers ask, several times each, and turns the answers into measurements:

- visibility %, with a confidence range
- AI share of voice against the competitors you choose
- position in the answer
- the sources AI cites
- what changed since your last run

No subscription. One flat price per AI answer, the same on every platform, so you know the cost before you start.

### Who it's for

- **SEO, GEO and marketing agencies:** measure and report AI visibility for every client, weekly or daily.
- **Brands and SaaS companies:** see whether AI assistants recommend you, or your competitors, for the questions that matter.
- **PR and communications teams:** track how often AI answers mention the brand and which sources they rely on.
- **Content teams:** find which sites AI cites for your topics, which shows where coverage would help.
- **Developers, automations and AI agents:** clean JSON metrics, run from the API, schedules or Apify's MCP server.

### How it works

1. You enter your **brand**, a few **competitors**, the **prompts** (the questions customers might ask, such as "best CRM for a small business") and your **target market**.
2. For each prompt, the Actor asks each chosen **AI platform** several times (**answers per prompt**). AI answers vary between runs, so one answer is an anecdote while several answers are a measurement.
3. Every answer is analysed for your brand and your competitors: whether each is named, how often, in what order, and which web pages are cited.
4. You get one row per AI answer, plus a **summary** row, a readable **REPORT** page and, on repeat runs, the **change since your last run**.

### Quick start (no code)

1. Enter **Brand to track** (for example `HubSpot`) and **Competitors** (`Salesforce`, `Zoho CRM`, `Pipedrive`). **Bulk edit** takes one per line.
2. Paste your **Prompts**, one per line.
3. Keep **AI platforms** as ChatGPT + Perplexity (add Gemini if you like) and **Answers per prompt** at 3.
4. Click **Start**. Open the **REPORT** record for the summary, or the dataset for per-answer detail.
5. To monitor over time, give the run a **Monitor name** and schedule it weekly. Each run is compared with the previous one automatically.

### What you get

#### Summary (last dataset row, also saved as `SUMMARY` and `REPORT`)

| Metric | Definition |
|---|---|
| `visibility_pct` | % of AI answers that name your brand |
| `visibility_ci95_pct` | 95% confidence range for visibility (Wilson interval). With few answers the range is wide; more samples narrow it |
| `share_of_voice_pct` | **AI share of voice**: your brand's appearances ÷ all appearances of tracked brands, counting each brand at most once per answer |
| `mention_share_pct` | The same, counting every mention (long answers that repeat a name count more) |
| `named_first_pct`, `avg_position_when_mentioned` | How often you are the first tracked brand named, and your average order of first mention |
| `visibility_score` + `visibility_score_factors` | 0 to 100 summary score; formula below |
| `by_platform`, `by_prompt` | The same metrics split by AI platform and by prompt, including the most visible brand per prompt |
| `competitor_comparison` | Visibility, share of voice, position and citation rate for every tracked brand, sorted |
| `citations` | Answers with sources, how often your site was cited, and the most cited domains |
| `prompts_with_brand`, `prompts_without_brand` | Where you appear, and where you don't |
| `change_vs_previous` | Change in visibility, share of voice and score since the last run; prompts gained and lost; competitor movements |

#### One row per AI answer

`prompt`, `platform`, `model`, `sample_number`, `web_search_used`, `brand_mentioned`, `brand_mentions_count`, `brand_position`, `brands_in_answer` (in order), `competitors_mentioned`, `competitor_mentions`, `share_of_voice`, `citation_count`, `citation_domains`, `brand_cited`, `competitor_citations`, `citations` (URL, title, domain, and the brand that owns the site), `checked_at`, `answered_at`, and stable IDs (`measurement_id`, `prompt_id`, `monitor_id`, `run_id`).

With **Include answer excerpts** on, each row also gets `answer_excerpt`: up to 300 characters of the answer around your brand's first mention, labelled `"AI-generated excerpt"` with the platform, model and answer time, and always delivered with the answer's cited sources. Gemini excerpts are never included. The product is the measurement, not the AI answer.

### How the measurements are defined

- **Position** is the order in which tracked brands are **first named** in an answer (1 = named first). It is not a claim that the AI "ranked" brands.
- **Brand detection** is our own deterministic matching, with no AI model involved:
  - It handles capitalisation, possessives ("HubSpot's"), punctuation, spacing variants ("Hub Spot"), multi-word names and dotted names ("monday.com").
  - Add website and extra names like this: `Zoho CRM (zoho.com) = Zoho, Zoho One`.
  - Brands that are also everyday words (Close, Copper, Monday) are only matched when written with a capital letter. Add a clearer alias such as `Close CRM` if needed.
- **Citations** come only from the platform's own source list. Links inside the answer text are not counted as brand mentions.
  - A cited page belongs to a brand when its domain matches the website you gave, or, if you gave none, when the domain contains the brand's distinctive name.
  - Gemini runs without live search, so it has no citations; they are reported as unavailable, never guessed.
- **Visibility score (`vis-v1`):** `100 × (0.5 × mention rate + 0.3 × prominence + 0.2 × citation rate)`
  - **Prominence** is the average of 1 ÷ position over all answers (named first = 1, second = 0.5, not named = 0).
  - **Citation rate** is the share of answers with sources that cite your site.
  - When no answer had sources, the weights become 0.625 and 0.375. The factors and weights are returned with every score.

### Repeated sampling

- The same question can produce different brand lists from one run to the next. Our own tests saw this on ChatGPT and Perplexity.
- **3 samples per prompt** is the default balance of cost and reliability. 5 samples tightens results; 1 gives a quick look.
- Visibility always comes with a 95% range, so you can tell a real change from noise.

### Monitoring over time

- Each complete run stores a compact summary (derived metrics only, no answer text) in a small named storage in **your own Apify account**.
- The next run of the same monitor reports what changed. A run that stopped early (for example at your maximum cost) is not stored, so it never becomes the baseline.
- Give runs a **Monitor name** to keep one history even when you edit prompts. Without a name, runs with identical settings are grouped automatically.
- Schedule the Actor (for example weekly) in Apify to build a trend.

### AI platforms

| Platform | How it is queried | Sources |
|---|---|---|
| **ChatGPT** | OpenAI API. By default the latest model decides whether to search the web, as it does for real users (it often answers from its own knowledge). Turn on **Always use web search for ChatGPT** to make every answer search and list its sources | When it searched |
| **Perplexity** | Perplexity Sonar API, which always searches | Yes |
| **Gemini** | Gemini API with model knowledge only. Live search grounding is off, because its terms don't allow analysing grounded results | No |

**Honest note:** answers come from the official APIs, not the consumer apps. Independent studies show API answers and consumer-app answers can differ in the sources they cite and the brands they name. Treat results as a consistent, repeatable measurement of AI behaviour rather than a screenshot of one user's app.

### Pricing

**One event: AI answer.** You pay the same price for every AI answer that is received and measured, on ChatGPT, Perplexity or Gemini, whether or not it searched the web. The current price is on the **Pricing** tab.

- **Cost of a run = prompts × platforms × answers per prompt × price per answer.** It is shown as the run's first status line ("Planned: 24 AI answers · at most $…") before any answer is requested.
- **Free:** failed or empty answers, answers that were never run, the summary row, the REPORT and the monitor history.
- **Maximum cost per run** is always respected: answers that would go over it are never requested or charged, and you still get the summary of everything measured. If your maximum is below the price of one answer, the run stops before asking anything.
- **Examples** (at $0.05 per answer): 1 prompt on ChatGPT, 1 answer = $0.05. 4 prompts × ChatGPT + Perplexity × 3 answers = 24 answers = $1.20. 10 prompts × 3 platforms × 3 answers = 90 answers = $4.50.
- Apify adds its standard run-start fee of $0.00005 per run.
- On Apify's free plan you get a small real sample (see Limits below).

### API, automations and AI agents

```bash
curl -X POST "https://api.apify.com/v2/acts/ACTOR_ID/run-sync-get-dataset-items" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{
    "brand": "HubSpot",
    "brandDomain": "hubspot.com",
    "competitors": ["Salesforce", "Zoho CRM (zoho.com)", "Pipedrive"],
    "prompts": ["best CRM for a small business", "best CRM for startups"],
    "platforms": ["chatgpt", "perplexity"],
    "samplesPerPrompt": 3,
    "monitorName": "HubSpot US weekly"
  }'
```

The response rows have `record_type: "answer"`, and the final row has `record_type: "summary"`.

**Input reference:**

| Field | Type | Default | Notes |
|---|---|---|---|
| `brand` | string | required | |
| `competitors` | string\[] | none | Up to 10; `Name (domain.com) = alias, alias` |
| `prompts` | string\[] | required | Up to 50 per run, 400 characters each |
| `platforms` | `chatgpt`, `perplexity`, `gemini` | `["chatgpt","perplexity"]` | |
| `samplesPerPrompt` | 1 to 5 | 3 | |
| `chatgptAlwaysSearch` | boolean | false | |
| `country` | US, GB, CA, AU, IN, IE, NZ, DE, FR, ES, IT, NL, BR, MX, JP, SE, PL, AE, SG, ZA | US | |
| `brandDomain` | string | none | |
| `brandAliases` | string\[] | none | |
| `includeCitations` | boolean | true | |
| `includeAnswerText` | boolean | false | Up to 300 characters around your brand's first mention, labelled AI-generated, with sources |
| `monitorName` | string | none | |
| `compareWithPrevious` | boolean | true | |

**Limits:**

- Up to 150 AI answers per run. For bigger jobs, split the prompts across runs or monitors.
- **Free Apify plan:** a small real sample, measured exactly like a paid run: your first prompt, 1 answer on up to 2 of your platforms (ChatGPT decides when to search). Free samples share a small daily allowance that resets at 00:00 UTC; when it is used up, free runs stop before asking anything and any paid Apify plan can run immediately.

### Acceptable use

- Track **businesses, products and brands**, not private individuals.
- By using this Actor you agree to follow the usage policies of the AI providers queried (OpenAI, Perplexity, Google).
- Do not use results to train AI models.
- Answer excerpts are optional, at most 300 characters, labelled as AI-generated with the platform, model and date, and always delivered with their cited sources.

### Accuracy and limitations

- **AI answers are probabilistic.** The same question can name different brands, in a different order, from one run to the next. That is why each prompt is asked several times and visibility comes with a 95% range. A change smaller than that range may be noise.
- **Official APIs, not consumer apps.** Answers come from the OpenAI, Perplexity and Gemini APIs. Consumer apps add personalisation, memory and their own search settings, so a person's app may answer differently.
- **Citations depend on the provider.** Only ChatGPT (when it searches) and Perplexity return sources. Which pages they cite, and how local they are to your target market, is the provider's choice. Gemini runs without live search and has no sources.
- **Brand detection is exact-name matching.** Misspellings and nicknames are missed unless you add them as other names. A brand that is also an everyday word (Close, Monday) is only counted when capitalised.
- **Position** is the order of first mention among the brands you track, not a ranking claimed by the AI.
- **Not affiliated** with OpenAI, Perplexity or Google. Product and company names belong to their owners. AI answers can be wrong; check anything important before acting on it.

### FAQ

**Why does ChatGPT sometimes show no sources?**
By default ChatGPT decides whether to search the web. When it answers from its own knowledge, there are no sources. Turn on **Always use web search for ChatGPT** to make it search every time.

**Why did ChatGPT name different brands this time?**
AI answers vary between runs even for the same question. Several answers per prompt turn that variation into a measurement with a range, instead of one anecdote.

**Why is my visibility range so wide?**
Few answers make a wide range. Add answers per prompt, or more prompts, to narrow it.

**Can I track several brands?**
Run once per brand, with its own monitor name, or list the other brands as competitors to see them side by side.

# Actor input Schema

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

Enter the brand you want to measure in AI answers.

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

Add the brands you want to compare against. Use the names they normally appear under in AI answers.

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

Enter the real questions your customers might ask an AI assistant. Results are measured separately for each prompt.

## `platforms` (type: `array`):

Choose which AI platforms to measure. Each selected platform adds answers to the run cost.

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

AI answers vary from run to run, so each prompt is asked this many times on each platform. 3 is recommended. Every answer is billed.

## `chatgptAlwaysSearch` (type: `boolean`):

Off: ChatGPT decides when to search the web, as it does for real users. On: every ChatGPT answer searches and lists its sources. The price per answer is the same.

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

Used to localize applicable AI requests and reporting.

## `brandDomain` (type: `string`):

Your site's domain (for example <code>hubspot.com</code>), used to spot when AI answers cite your own pages. If left empty, sites whose name matches your brand are counted.

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

Other ways people write your brand (for example <code>HubSpot CRM</code>, <code>Hubspot</code>). Capitalisation is handled automatically.

## `includeCitations` (type: `boolean`):

List the web pages each answer cited (ChatGPT and Perplexity, when they searched). Sources come from the AI provider and differ between platforms.

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

Add a short excerpt (up to 300 characters) around your brand's first mention, labelled as AI-generated and always delivered with its cited sources. Off by default: you get measurements, not AI answers. Never included for Gemini.

## `monitorName` (type: `string`):

Name this measurement (for example <code>HubSpot US weekly</code>) to compare every run with the previous one, even if you edit the prompts. Without a name, runs with identical settings are compared automatically.

## `compareWithPrevious` (type: `boolean`):

Show gains and losses since the last run of this monitor. History is kept in your own Apify account.

## Actor input object example

```json
{
  "brand": "HubSpot",
  "competitors": [
    "Salesforce",
    "Zoho CRM",
    "Pipedrive"
  ],
  "prompts": [
    "best CRM for a small business",
    "best CRM for startups",
    "best sales CRM",
    "CRM with marketing automation"
  ],
  "platforms": [
    "chatgpt",
    "perplexity"
  ],
  "samplesPerPrompt": 3,
  "chatgptAlwaysSearch": false,
  "country": "US",
  "includeCitations": true,
  "includeAnswerText": false,
  "compareWithPrevious": true
}
```

# Actor output Schema

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

One row per measured AI answer (brand named, position, brands in order, share of voice, citations), then one summary row. Filter by record\_type.

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

Readable report: visibility with its 95% range, share of voice, competitor comparison, results by platform and prompt, most cited sources and change since the last run.

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

The same summary as the dataset's final row.

## `runStatus` (type: `string`):

AI answers measured (billed), failed and not run (not billed), the charges Apify recorded, warnings and why a run stopped early.

# 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",
    "competitors": [
        "Salesforce",
        "Zoho CRM",
        "Pipedrive"
    ],
    "prompts": [
        "best CRM for a small business",
        "best CRM for startups",
        "best sales CRM",
        "CRM with marketing automation"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("koalabed/ai-brand-visibility").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",
    "competitors": [
        "Salesforce",
        "Zoho CRM",
        "Pipedrive",
    ],
    "prompts": [
        "best CRM for a small business",
        "best CRM for startups",
        "best sales CRM",
        "CRM with marketing automation",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("koalabed/ai-brand-visibility").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",
  "competitors": [
    "Salesforce",
    "Zoho CRM",
    "Pipedrive"
  ],
  "prompts": [
    "best CRM for a small business",
    "best CRM for startups",
    "best sales CRM",
    "CRM with marketing automation"
  ]
}' |
apify call koalabed/ai-brand-visibility --silent --output-dataset

```

## MCP server setup

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

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/zFDLKCE279FXq43tv/builds/mvtcoTcjZ9SWoDIO4/openapi.json
