# AI Search Visibility Tracker: ChatGPT, Perplexity

> Track brand mentions, share of voice and cited URLs in ChatGPT, Perplexity, Gemini, Google AI Overviews, AI Mode and Claude. Per prompt x engine: full answer, mention rank, sentiment, citations, your domain cited or not. Monitoring mode flags gained/lost mentions. GEO/AEO rank tracker.

- Category: AI search visibility
- Price: $40 per 1,000 × prompt check, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`.
- Store page: https://apify.com/wrenfield-data/ai-search-visibility-tracker
- Human page: https://wrenfielddata.com/tools/ai-search-visibility-tracker/
- OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~ai-search-visibility-tracker/builds/default/openapi.json
- MCP tool: https://mcp.apify.com?tools=wrenfield-data/ai-search-visibility-tracker (appears as `wrenfield-data--ai-search-visibility-tracker`)

## Call it

Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec):

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/wrenfield-data~ai-search-visibility-tracker/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"brands": ["HubSpot"], "domains": ["hubspot.com"], "competitors": ["Salesforce | salesforce.com", "Pipedrive | pipedrive.com"], "prompts": ["What is the best CRM for a small business?"], "promptsPerTopic": 3, "promptGeneration": "templates", "engines": ["chatgpt", "google_ai_mode"], "country": "United States", "language": "English", "monitoringMode": false, "monitoringStoreName": "ai-visibility-monitor", "maxChecks": 200, "chatgptWebSearch": true, "includeAnswerText": true, "caseSensitive": false, "maxConcurrency": 5}'
```

## Input

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `brands` | array | yes | `["HubSpot"]` | Your brand name, one per line. Add spelling variants after a \|, e.g. HubSpot \| HubSpot CRM. A token that looks like a domain (hubspot.com) is used as your domain. Matching is case-insensitive and whole-word. |
| `domains` | array |  |  | Your website domain(s), e.g. hubspot.com. Used to check whether AI answers cite your site (subdomains count). Writing the domain in the answer text also counts as a mention. |
| `competitors` | array |  |  | Competitor brands to compare with, one per line: Name \| variant \| domain.com. Used for share of voice, rank and citation comparisons. |
| `prompts` | array |  |  | Questions your buyers ask AI assistants, one per line, e.g. What is the best CRM for a small business?. Max 500 characters each. Every prompt is checked on every selected engine (1 prompt x 3 engines = 3 checks). Leave empty if you use seed topics. |
| `seedTopics` | array |  |  | Optional: product categories such as CRM software or running shoes for flat feet. The Actor generates buyer-intent questions ("What is the best ...", "alternatives to ", ...) for each topic and checks them too. |
| `promptsPerTopic` | integer |  | `3` | How many questions to generate per seed topic. |
| `promptGeneration` | string |  | `"templates"` | Templates: proven buyer-intent question patterns (stable from run to run, best for monitoring). AI-written: an AI model writes natural, varied buyer questions for each topic (at no extra charge; up to 20 topics). |
| `engines` | array |  | `["chatgpt", "perplexity", "google_ai_overview"]` | Engines to check every prompt on. Each prompt x engine is one check. ChatGPT, Gemini, Google AI Overviews and Google AI Mode are the real consumer answers (localized); Perplexity and Claude come from their official models. |
| `country` | string |  | `"United States"` | Where the questions are asked from: country name (Germany), 2-letter code (DE) or location code (2276). 190+ countries. |
| `language` | string |  | `"English"` | Language name (German) or code (de). Write your prompts in this language. |
| `monitoringMode` | boolean |  | `false` | Save results to a named key-value store and compare each prompt x engine with the previous run: flags gained/lost mentions, citations and rank changes, and adds share-of-voice changes to the summary. Schedule the Actor (e.g. weekly) to track AI visibility over time. |
| `trackingId` | string |  |  | Name of this tracking project, e.g. hubspot-us. Runs with the same ID are compared with each other. Default: derived from your brand, country and language. |
| `monitoringStoreName` | string |  | `"ai-visibility-monitor"` | Named key-value store (in your Apify account) that keeps the previous results. |
| `maxChecks` | integer |  | `200` | Upper limit of prompt x engine checks per run (cost control). The run also stops cleanly at your Maximum cost per run. |
| `chatgptWebSearch` | boolean |  | `true` | Ask ChatGPT to search the web (like ChatGPT Search) so answers cite sources. Turn off to see what ChatGPT says from memory. |
| `includeAnswerText` | boolean |  | `true` | Save the complete AI answer (markdown) in each row. |
| `caseSensitive` | boolean |  | `false` | Turn on for brand names that are also common words (e.g. Notion, Monday) to count only capitalized mentions. |
| `maxConcurrency` | integer |  | `5` | How many checks run at the same time. |

## Example input

```json
{
  "brands": [
    "HubSpot"
  ],
  "domains": [
    "hubspot.com"
  ],
  "competitors": [
    "Salesforce | salesforce.com",
    "Pipedrive | pipedrive.com"
  ],
  "prompts": [
    "What is the best CRM for a small business?"
  ],
  "promptsPerTopic": 3,
  "promptGeneration": "templates",
  "engines": [
    "chatgpt",
    "google_ai_mode"
  ],
  "country": "United States",
  "language": "English",
  "monitoringMode": false,
  "monitoringStoreName": "ai-visibility-monitor",
  "maxChecks": 200,
  "chatgptWebSearch": true,
  "includeAnswerText": true,
  "caseSensitive": false,
  "maxConcurrency": 5
}
```

## Output fields

One flat row per result:

| Field | Type | Description |
|---|---|---|
| `type` | string | check = one prompt answered by one AI engine; summary = share-of-voice row for one engine (or "all") and one brand |
| `prompt` | string | The question sent to the AI engine |
| `prompt_source` | string | input, template (generated from a seed topic) or ai (generated by AI from a seed topic) |
| `seed_topic` | string | Seed topic the prompt was generated from |
| `engine` | string | chatgpt, perplexity, gemini, google_ai_overview, google_ai_mode, claude (summary rows: also "all") |
| `engine_name` | string | Engine display name |
| `model` | string | Model / surface that produced the answer |
| `country` | string | Country used for the check |
| `language` | string | Language code |
| `status` | string | ok = answer received; no_answer = the engine showed no AI answer (e.g. no AI Overview for this query); error = check failed (not charged); incomplete = the engine returned a cut-off answer twice (not charged) |
| `note` | string | Explanation for no_answer / error / incomplete |
| `brand` | string | Your brand(s) |
| `brand_mentioned` | boolean | Your brand is mentioned in the answer |
| `brand_position` | integer | Rank of your brand among all tracked brands by first mention (1 = mentioned first) |
| `brand_mention_count` | integer | How many times your brand is mentioned |
| `brand_sentiment` | string | positive, neutral, negative or mixed (wording around your brand) |
| `brand_snippet` | string | Sentence where your brand is first mentioned |
| `your_domain_cited` | boolean | One of your domains is cited as a source (null if you gave no domain) |
| `your_cited_urls` | array | Your URLs cited as sources |
| `your_organic_rank` | integer | Google AI Overview engine only: rank of your domain in the top-10 organic results |
| `competitors_mentioned` | array | Tracked competitors mentioned in the answer |
| `first_mentioned_brand` | string | Tracked brand mentioned first |
| `brands_mentioned_count` | integer | Number of tracked brands mentioned |
| `brand_results` | array | Per tracked brand: mentioned, mention_count, position, sentiment, snippet, cited, cited_urls, position_among_all_brands, organic_rank |
| `other_brands_mentioned` | array | Other (untracked) brands the engine recognized in the answer (ChatGPT) |
| `cited_domains` | array | Unique domains cited as sources |
| `citations` | array/integer | Check rows: cited sources. Summary rows: checks citing the brand domain |
| `citations_count` | integer | Number of unique cited URLs |
| `fan_out_queries` | array | Web searches the engine ran to answer the prompt |
| `answer_text` | string | Full answer (markdown) |
| `answer_length` | integer | Answer length in characters |
| `change_status` | string | Monitoring: first_check, gained_mention, lost_mention, gained_citation, lost_citation, position_changed, competitors_changed, unchanged |
| `mention_change` | string | Monitoring: gained, lost or unchanged |
| `citation_change` | string | Monitoring: gained, lost or unchanged |
| `position_change` | integer | Monitoring: positions moved up (+) or down (-) since the previous run |
| `brands_gained` | array | Monitoring: tracked brands newly mentioned |
| `brands_lost` | array | Monitoring: tracked brands no longer mentioned |
| `previous_checked_at` | string | Monitoring: time of the previous check |
| `is_your_brand` | boolean | Summary: the row is about your brand |
| `checks` | integer | Summary: completed checks |
| `answers` | integer | Summary: checks with an AI answer |
| `mentions` | integer | Summary: checks mentioning the brand |
| `mention_rate` | number | Summary: mentions / checks (0-1) |
| `share_of_voice` | number | Summary: brand mentions / all tracked-brand mentions (0-1) |
| `avg_position` | number | Summary: average rank among tracked brands when mentioned |
| `top_position_rate` | number | Summary: share of checks where the brand is mentioned first |
| `citation_rate` | number | Summary: checks citing the brand domain / checks (null if no domain given) |
| `mention_rate_change` | number | Summary + monitoring: change vs previous run |
| `share_of_voice_change` | number | Summary + monitoring: change vs previous run |
| `citation_rate_change` | number | Summary + monitoring: change vs previous run |
| `checked_at` | string | When the row was produced (UTC) |

## Notes

- Auth: an Apify API token as `Authorization: Bearer <token>`; the MCP server also supports OAuth sign-in.
- Failed or empty results are not charged on most tools; check the pricing on the Store page.
- Questions: hello@wrenfielddata.com
