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

Ask ChatGPT, Perplexity, Gemini, and Claude your buyers' questions with your own API keys.  Each answer shows whether your brand is named, in what position, which competitors appear, and which sources are cited, plus a share-of-voice summary.  One flat price per answer.

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

## Pricing

from $21.25 / 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.
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

Find out whether AI assistants recommend your brand.  Give the Actor your brand, your competitors, and the questions your buyers ask, and it asks OpenAI, Perplexity, Gemini, and Anthropic (Claude) through their official APIs.  Every answer comes back as a record that says whether your brand was named, in what position among the brands you track, which competitors appeared, and which sources were cited.  A share-of-voice summary closes each run.

You bring your own API keys, and you pay each AI provider for its own answers.  The Actor charges one flat price per answer on top of that.

### What does it do?

- Asks each prompt to every provider you added a key for, as many times as you choose, because AI answers change from one ask to the next.
- Finds your brand, its other names, and each competitor in the answer as whole words, ignoring case, so "Apify" is found in "apify's" but not in "apifying".  Brand names that only appear inside a link are not counted.
- Ranks the tracked brands by where each is first named, so position 1 means the answer named that brand before any other tracked brand.
- Collects the source links the provider returns, such as Perplexity's citations and search results, plus links written in the answer, and checks whether any of them is on your website.
- Closes the run with one summary record: for each brand, how many answers named it, its share of voice, its average position, and how often it came first, plus your brand's numbers for each provider.
- Retries a provider that is busy or rate limited, up to 3 tries, and honors the provider's own wait time.  A key the provider refuses, a model it does not have, or an account with no credit stops that provider for the rest of the run, so one bad key never fails the others.

### Who is it for?

- Marketing and SEO teams who want to know whether AI assistants recommend their brand.
- Agencies that report AI search visibility to clients.
- Founders and product marketers who track how they compare with competitors in AI answers.
- Analysts who study which sources AI assistants cite.

### Your API keys

Keys go in the secret fields of the input form, so Apify stores them encrypted and hides them in the run's input.  The Actor sends each key only to its own provider, never writes it to the log, the dataset, or the key-value store, and removes anything that looks like a key from provider error messages before showing them.

- **OpenAI:** [platform.openai.com/api-keys](https://platform.openai.com/api-keys)
- **Perplexity:** [perplexity.ai/settings/api](https://www.perplexity.ai/settings/api)
- **Gemini:** [aistudio.google.com/apikey](https://aistudio.google.com/apikey)
- **Anthropic:** [console.anthropic.com](https://console.anthropic.com/)

Add at least one key.  A run without any key finishes successfully with a message saying so, asks nothing, and charges nothing beyond the Actor start.  A run where every provider refuses its key also finishes, with a message naming each refused key, and failed answers are free.  Both leave a free setup record in the dataset that says what to fix.

### How to use

1. Get an API key from at least one provider: OpenAI, Perplexity, Google Gemini, or Anthropic.
2. Open the Actor in Apify Console and enter your brand, competitors, and the questions your buyers ask.
3. Paste your keys into the secret fields under **AI provider keys and models**.
4. Click **Start** and wait for the run to finish.
5. Open the **Output** tab to read each answer and the share-of-voice summary, then export them as JSON, CSV, Excel, or XML.
6. To track visibility over time, add a schedule.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `brand` | string | Your brand as people write it, like `Apify`.  Required. |
| `brandAliases` | list of strings | Other names that count as your brand.  Up to 10. |
| `brandDomain` | string | Your website, like `apify.com`, to check whether answers cite it. |
| `competitors` | list of strings | Competitors to count, one per line.  Add other names after a bar, like `Bright Data \| BrightData`.  Up to 25. |
| `prompts` | list of strings | Questions your buyers ask, one per line.  Required, up to 100. |
| `repeats` | integer | Times to ask each prompt of each provider.  Default 1, up to 5. |
| `openaiApiKey` | secret string | Your OpenAI API key. |
| `openaiModel` | string | OpenAI model.  Default `gpt-4.1-mini`. |
| `perplexityApiKey` | secret string | Your Perplexity API key. |
| `perplexityModel` | string | Perplexity model.  Default `sonar`. |
| `geminiApiKey` | secret string | Your Gemini API key. |
| `geminiModel` | string | Gemini model.  Default `gemini-3.5-flash-lite`. |
| `anthropicApiKey` | secret string | Your Anthropic API key. |
| `anthropicModel` | string | Anthropic model.  Default `claude-haiku-4-5`. |
| `maxAnswerTokens` | integer | Most tokens each answer may use.  Default 1,000, from 100 to 4,000. |
| `maxConcurrency` | integer | Questions asked at the same time of each provider.  Default 2, up to 5. |

```json
{
  "brand": "Apify",
  "brandDomain": "apify.com",
  "competitors": ["Bright Data", "Oxylabs", "ScrapingBee"],
  "prompts": [
    "What is the best web scraping platform?",
    "Which tools can extract data from any website without code?"
  ],
  "repeats": 2,
  "perplexityApiKey": "pplx-...",
  "openaiApiKey": "sk-..."
}
```

That input asks 2 prompts, 2 times each, of 2 providers, for 8 answers.

### Output

One record per answer, with `recordType` set to `answer`.  An answer the provider could not give, for example because it refused the key or stayed busy, still gets a record with `status` set to `failed` and the reason in `error`, and that record is not charged.

A run that cannot ask any provider, because no key was added or every provider refused its key, leaves one free `setup` record with `status` set to `setupNeeded` and what to fix in `error`, so the dataset is never empty.

```json
{
  "recordType": "answer",
  "status": "ok",
  "error": null,
  "provider": "Perplexity",
  "model": "sonar",
  "prompt": "What is the best web scraping platform?",
  "promptNumber": 1,
  "repeat": 1,
  "answer": "The most popular choices are Bright Data, Apify, and Oxylabs.  Apify stands out for its ready-made scrapers.",
  "brand": "Apify",
  "brandMentioned": true,
  "brandPosition": 2,
  "brandMentionCount": 2,
  "competitorsMentioned": [
    "Bright Data",
    "Oxylabs"
  ],
  "mentions": [
    {
      "name": "Apify",
      "isYourBrand": true,
      "position": 2,
      "count": 2
    },
    {
      "name": "Bright Data",
      "isYourBrand": false,
      "position": 1,
      "count": 1
    },
    {
      "name": "Oxylabs",
      "isYourBrand": false,
      "position": 3,
      "count": 1
    }
  ],
  "citations": [
    "https://apify.com/store",
    "https://www.g2.com/categories/web-scraping"
  ],
  "brandDomainCited": true,
  "answeredAt": "2026-11-01T18:00:00+00:00",
  "answersChecked": null,
  "shareOfVoice": null,
  "byProvider": null
}
```

The last record of a run has `recordType` set to `summary`.  It counts only answers that came back.  `mentionRate` is the share of answers that named the brand, and `shareOfVoice` is the brand's share of all brand mentions, so the share of voice of all tracked brands adds up to about 1.  Positions are averaged over the answers that named the brand.  The per-answer fields are empty in the summary.

```json
{
  "recordType": "summary",
  "status": "ok",
  "brand": "Apify",
  "brandMentioned": true,
  "competitorsMentioned": [
    "Bright Data",
    "Oxylabs"
  ],
  "answeredAt": "2026-11-01T18:00:00+00:00",
  "answersChecked": 1,
  "shareOfVoice": [
    {
      "name": "Apify",
      "isYourBrand": true,
      "answersMentioning": 1,
      "mentionRate": 1.0,
      "shareOfVoice": 0.333,
      "averagePosition": 2,
      "firstMentions": 0
    },
    {
      "name": "Bright Data",
      "isYourBrand": false,
      "answersMentioning": 1,
      "mentionRate": 1.0,
      "shareOfVoice": 0.333,
      "averagePosition": 1,
      "firstMentions": 1
    },
    {
      "name": "Oxylabs",
      "isYourBrand": false,
      "answersMentioning": 1,
      "mentionRate": 1.0,
      "shareOfVoice": 0.333,
      "averagePosition": 3,
      "firstMentions": 0
    }
  ],
  "byProvider": [
    {
      "provider": "Perplexity",
      "model": "sonar",
      "answers": 1,
      "brandMentionRate": 1.0,
      "brandAveragePosition": 2,
      "brandDomainCitedRate": 1.0
    }
  ]
}
```

### Pricing

This Actor uses pay-per-event pricing.

- **AI answer:** $25.00 per 1,000 answers ($0.025 each), whether your brand was named or not.  Failed answers and the summary record are free of charge.
- **Store discounts:** Bronze $23.75, Silver $22.50, and Gold $21.25 per 1,000 answers.
- **Actor start:** Apify's standard start event ($0.00005).

**You also pay your own AI API costs.**  Each provider bills your account directly for the answers asked with your key, at its own prices, which this Actor does not see or control.  With the default small models and a 1,000 token limit, that is usually a fraction of a cent per answer, but check each provider's pricing page, and set a spending limit on your provider accounts if you want a hard cap.

100 answers cost $2.50 in Actor charges.  Asking 10 prompts, 3 times each, of 4 providers gives 120 answers and costs $3.00.  You can cap any run with Apify's maximum charge setting.  The Actor stops asking new questions once your limit can no longer pay for them, so you are only charged for answers that actually reach your dataset.

#### Estimated compute cost

Default memory is 512 MB.  The Actor spends almost all of its time waiting for the AI providers, so platform usage is small next to the answer charges, roughly the cost of a run of the same length that does nothing.

### Things to know

- The Actor asks the same API models that power the assistants, not the consumer chat apps, so answers can differ from what a signed-in person sees in ChatGPT, Gemini, or Claude.  The APIs do not know who is asking or where.
- Perplexity searches the web for every answer and returns its sources.  The OpenAI, Gemini, and Anthropic models listed above answer from what they learned in training unless you pick a model that searches, so their answers often have no citations.
- Gemini 2.5 models and OpenAI reasoning models spend part of the token limit on thinking.  If their answers come back short or empty, raise `maxAnswerTokens`.
- Brand matching is by name.  A brand whose name is also a common word, like Notion or Monday, can be counted where the answer uses the word in its plain sense, so give such brands a more specific alias and check the answers.
- Runs time out after one hour by default.  Very large runs, like 100 prompts asked 5 times of 4 providers, can take longer, so raise the run timeout in the run options or split the prompts across tasks.
- If the platform moves a run to another server, it resumes where it stopped and never delivers or charges an answer twice.

### Testing status

The provider code is tested against mocked provider responses shaped like each provider's documented API, and those automated tests run on every change.  Runs on Apify without keys have been checked end to end.  No run with live provider keys has been done yet, so an answer from a real provider could still surprise the parser.  If a provider's answer looks wrong or a provider changes its API, please report it in the Issues tab and it will be fixed.

### API and integrations

You can start this Actor and read its results with the [Apify API](https://docs.apify.com/api/v2), the Apify Python and JavaScript clients, or the Apify CLI.  The API returns each run's dataset in the same formats as the Console.

Apify integrations can pass results on when a run finishes, for example to Google Sheets, Slack, Zapier, Make, or your own webhook.  Set them up on the Actor's **Integrations** tab, and pair them with a schedule for a hands-off feed.

### FAQ

**Does the Actor use my ChatGPT Plus or other chat subscription?**  No.  It needs an API key from each provider's developer platform, which is billed separately from chat subscriptions.

**Why does the same prompt give different answers?**  AI models pick words with some randomness, and Perplexity's search results change over time.  Set `repeats` to 2 or 3 to see how steady the answers are.

**Can I track this every week?**  Yes.  Save your input as a task, then add a schedule to it in Apify Console, and compare the summary records over time.

**Is my key safe?**  The key is stored in Apify's encrypted secret input, sent only to its provider over HTTPS, and never logged or saved by the Actor.  You can also create a separate key for this Actor and delete it whenever you like.

### Related Actors

- [Website Contact Enrichment (Emails, Phones)](https://apify.com/maniginam/website-contact-enrichment): emails, phone numbers, and social links from company websites.
- [Greenhouse, Lever & Workday Jobs Tracker](https://apify.com/maniginam/career-site-jobs-hiring-tracker): open jobs from Greenhouse, Lever, Ashby, and Workday career sites.
- [News & Brand Mention Monitor (Google News + RSS)](https://apify.com/maniginam/news-brand-mention-monitor): news mentions of your brand in Google News and RSS feeds.

### Feedback and custom requests

Found a bug, a wrong value, or a source that changed?  Open an issue in the Issues tab on this Actor's page.  Need another field, filter, or source, or a version built for your team?  Describe it in the Issues tab as a custom request.

# Changelog

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

# Actor input Schema

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

The brand you want AI assistants to recommend, as people write it, like Apify.

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

Other spellings or product names that count as your brand, like Apify Store.  Up to 10.

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

Your domain, like apify.com.  Each answer then says whether a cited source is on your website.

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

Competitors to count, one per line.  Add other names after a bar, like Bright Data | BrightData.  Up to 25.

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

Questions your buyers ask AI assistants, one per line.  Each prompt is asked once per provider and repeat.  Up to 100.

## `repeats` (type: `integer`):

AI answers change from one ask to the next, so asking the same prompt 2 or 3 times gives a steadier picture.  Every repeat is a separate charged answer.

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

Your own OpenAI API key, from platform.openai.com/api-keys.  The Actor sends it only to OpenAI, never logs it, and never saves it.  Leave it empty to skip OpenAI.  OpenAI bills you for the answers.

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

Model to ask, like gpt-4.1-mini, gpt-4.1, or gpt-4o.

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

Your own Perplexity API key, from perplexity.ai/settings/api.  The Actor sends it only to Perplexity, never logs it, and never saves it.  Leave it empty to skip Perplexity.  Perplexity bills you for the answers.

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

Model to ask, like sonar or sonar-pro.

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

Your own Gemini API key, from aistudio.google.com/apikey.  The Actor sends it only to Gemini, never logs it, and never saves it.  Leave it empty to skip Gemini.  Gemini bills you for the answers.

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

Model to ask, like gemini-3.5-flash-lite or gemini-3.8-flash.

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

Your own Anthropic API key, from console.anthropic.com.  The Actor sends it only to Anthropic, never logs it, and never saves it.  Leave it empty to skip Anthropic.  Anthropic bills you for the answers.

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

Model to ask, like claude-haiku-4-5 or claude-sonnet-4-5.

## `maxAnswerTokens` (type: `integer`):

Most tokens each answer may use.  Longer answers name more brands and cost more on your provider bill.

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

How many questions each provider is asked at the same time.  Lower it if a provider says your key is over its rate limit.

## Actor input object example

```json
{
  "brand": "Apify",
  "competitors": [
    "Bright Data",
    "Oxylabs"
  ],
  "prompts": [
    "What is the best web scraping platform?",
    "Which tools can extract data from any website without code?"
  ],
  "repeats": 1,
  "openaiModel": "gpt-4.1-mini",
  "perplexityModel": "sonar",
  "geminiModel": "gemini-3.5-flash-lite",
  "anthropicModel": "claude-haiku-4-5",
  "maxAnswerTokens": 1000,
  "maxConcurrency": 2
}
```

# Actor output Schema

## `results` (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": "Apify",
    "competitors": [
        "Bright Data",
        "Oxylabs"
    ],
    "prompts": [
        "What is the best web scraping platform?",
        "Which tools can extract data from any website without code?"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maniginam/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": "Apify",
    "competitors": [
        "Bright Data",
        "Oxylabs",
    ],
    "prompts": [
        "What is the best web scraping platform?",
        "Which tools can extract data from any website without code?",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("maniginam/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": "Apify",
  "competitors": [
    "Bright Data",
    "Oxylabs"
  ],
  "prompts": [
    "What is the best web scraping platform?",
    "Which tools can extract data from any website without code?"
  ]
}' |
apify call maniginam/ai-brand-visibility-tracker --silent --output-dataset

```

## MCP server setup

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