# ChatGPT Brand Visibility Tracker (AI SEO / GEO) (`hanielazevedo/ai-search-tracker`) Actor

Track whether ChatGPT mentions, ranks and cites your brand vs competitors for buyer prompts. Official OpenAI API with web search: mention rate, position, sentiment, cited URLs, share of voice, visibility score, baseline diff. No API key needed.

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

## Pricing

from $45.00 / 1,000 chatgpt check (web search)s

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

## ChatGPT Brand Visibility Tracker (AI SEO / GEO)

Find out whether ChatGPT recommends your brand. The Actor asks ChatGPT the questions your buyers ask (for example "What are the best CRM tools for a small business?"). For each answer it reports whether your brand was **mentioned**, at what **position**, with what **sentiment**, whether your site was **cited**, and how you compare with your **competitors**.

It runs on the **official OpenAI API** (Responses API with the built-in `web_search` tool, the same kind of search-grounded answer ChatGPT gives). There is no browser scraping and no login, and you do not need your own API key.

> Not affiliated with, endorsed by or sponsored by OpenAI. "ChatGPT" is a trademark of OpenAI and is used here only to describe the data source.

### What you get

**One dataset row per check** (one check is one prompt × one sample):

| Field | Meaning |
|---|---|
| `brandMentioned`, `brandPosition` | Whether your brand appears, and its rank among **all** brands the answer names (1 = first) |
| `brandSentiment` | positive / neutral / negative / mixed |
| `brandCited`, `brandCitationRank` | Whether a URL on your domain is among the answer's citations, and its rank |
| `brandsNamed` | Every brand in the answer, in order, with sentiment, including competitors you did not list |
| `competitors` | The same metrics for each competitor you track |
| `citations`, `citedDomains`, `sourceUrls`, `searchQueries` | Clickable cited URLs with titles, the sources consulted, and the search queries ChatGPT ran |
| `answer`, `brandExcerpt` | The full answer text and the passage where your brand appears |
| `estimatedOpenAiCostUsd`, `usage` | Tokens and the estimated API cost of the check (for transparency) |
| `diff` | Your previous mention rate and position for this prompt (when a history store is used) |

**A run summary** (key-value store record `OUTPUT`) contains:

- mention rate, average position, top-1 and top-3 rates
- **visibility score** (0–100) = the average over all checks of 1/position, scored 0 when the brand is not mentioned
- **share of voice** = your mentions ÷ mentions of all tracked brands
- citation rate, top cited domains, and the prompts where you are missing
- a change report against your last run

The checks and the share-of-voice table are also saved as CSV (`CHECKS.csv`, `SHARE_OF_VOICE.csv`).

### Input

```json
{
  "brand": "HubSpot | hubspot.com",
  "competitors": ["Salesforce | salesforce.com", "Pipedrive | pipedrive.com", "Zoho CRM | Zoho | zoho.com"],
  "keywords": ["CRM software for small businesses"],
  "prompts": ["What is the easiest CRM for a 10-person sales team?"],
  "promptVariants": 3,
  "country": "US",
  "language": "en",
  "webSearch": true,
  "samplesPerPrompt": 1,
  "baselineStoreName": "my-brand-ai-visibility"
}
```

- **Brand format:** `Name | alias | domain.com`. Aliases improve matching. The domain is used to detect citations of your site.
- **Keywords** are turned into realistic buyer prompts (English, Portuguese and Spanish templates). Your brand is **never** put into the prompt, so the answer is not biased toward it.
- **samplesPerPrompt:** AI answers vary from one request to the next. Sampling each prompt 2–3 times gives a steadier mention rate.
- **webSearch:** on gives a search-grounded answer with citations. Off gives an answer from the model's own knowledge, which is a cheaper check.
- **baselineStoreName:** a named key-value store in your account. Each run is compared with the previous run saved there. Schedule the Actor weekly to track trends.
- **Demo mode (`mockMode`):** produces realistic **synthetic** answers so you can preview the output for free. Demo answers are not real ChatGPT data.

### Pricing

Pricing is **pay per event**: you pay **per successful check**, and checks that fail (OpenAI errors, timeouts, empty answers) are **not charged**. A check made with web search costs more than one made without it (see the Pricing tab). The run stops before your **max total charge** is reached, so a check that cannot be billed is never sent. On the Apify **free plan**, each run is limited to a few demo checks.

### How this compares (Apify Store, checked 2026-10-31)

| | This Actor | apify/chatgpt-search-scraper | santhej/ai-rank-tracker-pro |
|---|---|---|---|
| How answers are obtained (per Store description) | Official OpenAI API | "Scrape ChatGPT Search results at scale without an API" | "No API keys" |
| Price shown on Store (2026-10-31) | see Pricing tab | $0.20 per result on the free tier, $0.005 on Bronze | $0.05 per platform check + $0.25 per report |
| Run success rate shown on Store (30 days, 2026-10-31) | new | 88.2% | 98.4% |
| Engines | ChatGPT | ChatGPT | 5 AI platforms |

Figures for other Actors are quoted from their public Apify Store pages/API on 2026-10-31 (success rate = succeeded ÷ total runs in the last 30 days) and may have changed since.

### Limits and notes

- AI answers are non-deterministic, so read the results as samples. Use `samplesPerPrompt` and scheduled runs to see trends.
- The answers come from the API with web search. They can differ from what a logged-in ChatGPT user sees, which depends on memory, personalization and the app version.
- Position counts every brand the AI names. With `analysisMode: "rules"`, only your tracked brands are counted.
- Citations are returned exactly as given by the API. If you display results publicly, keep the citations visible and clickable.

# Actor input Schema

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

Brand to track. A name, a domain, or "Name | alias | domain.com" (aliases improve matching; the domain is used to detect when ChatGPT cites your site).

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

Other spellings or product names that count as your brand (e.g. "HubSpot CRM").

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

Up to 20 competitors, same format as the brand: "Name | alias | domain.com". Used for share of voice and ranking.

## `keywords` (type: `array`):

Topics your buyers ask about. Each keyword becomes realistic prompts (see "Prompt variants per keyword"). Your brand is never inserted into the prompt.

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

Questions to ask ChatGPT word for word, in addition to the keyword prompts.

## `promptVariants` (type: `integer`):

How many phrasings to generate for each keyword ("best ...", "which ... do you recommend", "... compared", ...).

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

Language ChatGPT answers in. Keyword prompt templates exist for English, Portuguese and Spanish (other languages use the English templates; exact prompts are sent as written).

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

Two-letter ISO country code used as the approximate searcher location (e.g. US, BR, GB). Leave empty for no location.

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

On: ChatGPT searches the web and cites sources (what most users see today). Off: answer from model memory only (cheaper event, no citations).

## `model` (type: `string`):

OpenAI model used to answer. Same price per check for every model.

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

AI answers vary. Ask each prompt up to 3 times for a steadier mention rate. Each sample is one check.

## `analysisMode` (type: `string`):

AI extraction lists every brand the answer names, so positions count unknown competitors too. Rules only matches your tracked names.

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

Hard cap on checks (prompts x samples) in this run. Each successful check is one charged event.

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

Checks run in parallel.

## `baselineStoreName` (type: `string`):

Optional named key-value store in your account. The run compares results with the last run saved there and reports what changed.

## `saveBaseline` (type: `boolean`):

Only used with a history store name.

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

Currently ChatGPT only.

## `mockMode` (type: `boolean`):

Generates realistic synthetic answers without calling OpenAI, to preview the output format. Never charged, max 20 checks. Results are NOT real ChatGPT data.

## Actor input object example

```json
{
  "brand": "HubSpot | hubspot.com",
  "brandAliases": [],
  "competitors": [
    "Salesforce | salesforce.com",
    "Pipedrive | pipedrive.com",
    "Zoho CRM | Zoho | zoho.com"
  ],
  "keywords": [
    "CRM software for small businesses"
  ],
  "prompts": [
    "What is the easiest CRM for a 10-person sales team?"
  ],
  "promptVariants": 3,
  "language": "en",
  "country": "US",
  "webSearch": true,
  "model": "gpt-6-luna",
  "samplesPerPrompt": 1,
  "analysisMode": "llm",
  "maxChecks": 50,
  "maxConcurrency": 5,
  "saveBaseline": true,
  "engines": [
    "chatgpt"
  ],
  "mockMode": false
}
```

# Actor output Schema

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

No description

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

No description

## `checksCsv` (type: `string`):

No description

## `sovCsv` (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": "HubSpot | hubspot.com",
    "brandAliases": [],
    "competitors": [
        "Salesforce | salesforce.com",
        "Pipedrive | pipedrive.com",
        "Zoho CRM | Zoho | zoho.com"
    ],
    "keywords": [
        "CRM software for small businesses"
    ],
    "prompts": [
        "What is the easiest CRM for a 10-person sales team?"
    ],
    "baselineStoreName": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("hanielazevedo/ai-search-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",
    "brandAliases": [],
    "competitors": [
        "Salesforce | salesforce.com",
        "Pipedrive | pipedrive.com",
        "Zoho CRM | Zoho | zoho.com",
    ],
    "keywords": ["CRM software for small businesses"],
    "prompts": ["What is the easiest CRM for a 10-person sales team?"],
    "baselineStoreName": "",
}

# Run the Actor and wait for it to finish
run = client.actor("hanielazevedo/ai-search-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",
  "brandAliases": [],
  "competitors": [
    "Salesforce | salesforce.com",
    "Pipedrive | pipedrive.com",
    "Zoho CRM | Zoho | zoho.com"
  ],
  "keywords": [
    "CRM software for small businesses"
  ],
  "prompts": [
    "What is the easiest CRM for a 10-person sales team?"
  ],
  "baselineStoreName": ""
}' |
apify call hanielazevedo/ai-search-tracker --silent --output-dataset

```

## MCP server setup

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